jquery.jqgrid.src.js 762 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830483148324833483448354836483748384839484048414842484348444845484648474848484948504851485248534854485548564857485848594860486148624863486448654866486748684869487048714872487348744875487648774878487948804881488248834884488548864887488848894890489148924893489448954896489748984899490049014902490349044905490649074908490949104911491249134914491549164917491849194920492149224923492449254926492749284929493049314932493349344935493649374938493949404941494249434944494549464947494849494950495149524953495449554956495749584959496049614962496349644965496649674968496949704971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040504150425043504450455046504750485049505050515052505350545055505650575058505950605061506250635064506550665067506850695070507150725073507450755076507750785079508050815082508350845085508650875088508950905091509250935094509550965097509850995100510151025103510451055106510751085109511051115112511351145115511651175118511951205121512251235124512551265127512851295130513151325133513451355136513751385139514051415142514351445145514651475148514951505151515251535154515551565157515851595160516151625163516451655166516751685169517051715172517351745175517651775178517951805181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250525152525253525452555256525752585259526052615262526352645265526652675268526952705271527252735274527552765277527852795280528152825283528452855286528752885289529052915292529352945295529652975298529953005301530253035304530553065307530853095310531153125313531453155316531753185319532053215322532353245325532653275328532953305331533253335334533553365337533853395340534153425343534453455346534753485349535053515352535353545355535653575358535953605361536253635364536553665367536853695370537153725373537453755376537753785379538053815382538353845385538653875388538953905391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460546154625463546454655466546754685469547054715472547354745475547654775478547954805481548254835484548554865487548854895490549154925493549454955496549754985499550055015502550355045505550655075508550955105511551255135514551555165517551855195520552155225523552455255526552755285529553055315532553355345535553655375538553955405541554255435544554555465547554855495550555155525553555455555556555755585559556055615562556355645565556655675568556955705571557255735574557555765577557855795580558155825583558455855586558755885589559055915592559355945595559655975598559956005601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670567156725673567456755676567756785679568056815682568356845685568656875688568956905691569256935694569556965697569856995700570157025703570457055706570757085709571057115712571357145715571657175718571957205721572257235724572557265727572857295730573157325733573457355736573757385739574057415742574357445745574657475748574957505751575257535754575557565757575857595760576157625763576457655766576757685769577057715772577357745775577657775778577957805781578257835784578557865787578857895790579157925793579457955796579757985799580058015802580358045805580658075808580958105811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880588158825883588458855886588758885889589058915892589358945895589658975898589959005901590259035904590559065907590859095910591159125913591459155916591759185919592059215922592359245925592659275928592959305931593259335934593559365937593859395940594159425943594459455946594759485949595059515952595359545955595659575958595959605961596259635964596559665967596859695970597159725973597459755976597759785979598059815982598359845985598659875988598959905991599259935994599559965997599859996000600160026003600460056006600760086009601060116012601360146015601660176018601960206021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090609160926093609460956096609760986099610061016102610361046105610661076108610961106111611261136114611561166117611861196120612161226123612461256126612761286129613061316132613361346135613661376138613961406141614261436144614561466147614861496150615161526153615461556156615761586159616061616162616361646165616661676168616961706171617261736174617561766177617861796180618161826183618461856186618761886189619061916192619361946195619661976198619962006201620262036204620562066207620862096210621162126213621462156216621762186219622062216222622362246225622662276228622962306231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300630163026303630463056306630763086309631063116312631363146315631663176318631963206321632263236324632563266327632863296330633163326333633463356336633763386339634063416342634363446345634663476348634963506351635263536354635563566357635863596360636163626363636463656366636763686369637063716372637363746375637663776378637963806381638263836384638563866387638863896390639163926393639463956396639763986399640064016402640364046405640664076408640964106411641264136414641564166417641864196420642164226423642464256426642764286429643064316432643364346435643664376438643964406441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510651165126513651465156516651765186519652065216522652365246525652665276528652965306531653265336534653565366537653865396540654165426543654465456546654765486549655065516552655365546555655665576558655965606561656265636564656565666567656865696570657165726573657465756576657765786579658065816582658365846585658665876588658965906591659265936594659565966597659865996600660166026603660466056606660766086609661066116612661366146615661666176618661966206621662266236624662566266627662866296630663166326633663466356636663766386639664066416642664366446645664666476648664966506651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720672167226723672467256726672767286729673067316732673367346735673667376738673967406741674267436744674567466747674867496750675167526753675467556756675767586759676067616762676367646765676667676768676967706771677267736774677567766777677867796780678167826783678467856786678767886789679067916792679367946795679667976798679968006801680268036804680568066807680868096810681168126813681468156816681768186819682068216822682368246825682668276828682968306831683268336834683568366837683868396840684168426843684468456846684768486849685068516852685368546855685668576858685968606861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930693169326933693469356936693769386939694069416942694369446945694669476948694969506951695269536954695569566957695869596960696169626963696469656966696769686969697069716972697369746975697669776978697969806981698269836984698569866987698869896990699169926993699469956996699769986999700070017002700370047005700670077008700970107011701270137014701570167017701870197020702170227023702470257026702770287029703070317032703370347035703670377038703970407041704270437044704570467047704870497050705170527053705470557056705770587059706070617062706370647065706670677068706970707071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140714171427143714471457146714771487149715071517152715371547155715671577158715971607161716271637164716571667167716871697170717171727173717471757176717771787179718071817182718371847185718671877188718971907191719271937194719571967197719871997200720172027203720472057206720772087209721072117212721372147215721672177218721972207221722272237224722572267227722872297230723172327233723472357236723772387239724072417242724372447245724672477248724972507251725272537254725572567257725872597260726172627263726472657266726772687269727072717272727372747275727672777278727972807281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350735173527353735473557356735773587359736073617362736373647365736673677368736973707371737273737374737573767377737873797380738173827383738473857386738773887389739073917392739373947395739673977398739974007401740274037404740574067407740874097410741174127413741474157416741774187419742074217422742374247425742674277428742974307431743274337434743574367437743874397440744174427443744474457446744774487449745074517452745374547455745674577458745974607461746274637464746574667467746874697470747174727473747474757476747774787479748074817482748374847485748674877488748974907491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560756175627563756475657566756775687569757075717572757375747575757675777578757975807581758275837584758575867587758875897590759175927593759475957596759775987599760076017602760376047605760676077608760976107611761276137614761576167617761876197620762176227623762476257626762776287629763076317632763376347635763676377638763976407641764276437644764576467647764876497650765176527653765476557656765776587659766076617662766376647665766676677668766976707671767276737674767576767677767876797680768176827683768476857686768776887689769076917692769376947695769676977698769977007701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770777177727773777477757776777777787779778077817782778377847785778677877788778977907791779277937794779577967797779877997800780178027803780478057806780778087809781078117812781378147815781678177818781978207821782278237824782578267827782878297830783178327833783478357836783778387839784078417842784378447845784678477848784978507851785278537854785578567857785878597860786178627863786478657866786778687869787078717872787378747875787678777878787978807881788278837884788578867887788878897890789178927893789478957896789778987899790079017902790379047905790679077908790979107911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980798179827983798479857986798779887989799079917992799379947995799679977998799980008001800280038004800580068007800880098010801180128013801480158016801780188019802080218022802380248025802680278028802980308031803280338034803580368037803880398040804180428043804480458046804780488049805080518052805380548055805680578058805980608061806280638064806580668067806880698070807180728073807480758076807780788079808080818082808380848085808680878088808980908091809280938094809580968097809880998100810181028103810481058106810781088109811081118112811381148115811681178118811981208121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190819181928193819481958196819781988199820082018202820382048205820682078208820982108211821282138214821582168217821882198220822182228223822482258226822782288229823082318232823382348235823682378238823982408241824282438244824582468247824882498250825182528253825482558256825782588259826082618262826382648265826682678268826982708271827282738274827582768277827882798280828182828283828482858286828782888289829082918292829382948295829682978298829983008301830283038304830583068307830883098310831183128313831483158316831783188319832083218322832383248325832683278328832983308331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400840184028403840484058406840784088409841084118412841384148415841684178418841984208421842284238424842584268427842884298430843184328433843484358436843784388439844084418442844384448445844684478448844984508451845284538454845584568457845884598460846184628463846484658466846784688469847084718472847384748475847684778478847984808481848284838484848584868487848884898490849184928493849484958496849784988499850085018502850385048505850685078508850985108511851285138514851585168517851885198520852185228523852485258526852785288529853085318532853385348535853685378538853985408541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610861186128613861486158616861786188619862086218622862386248625862686278628862986308631863286338634863586368637863886398640864186428643864486458646864786488649865086518652865386548655865686578658865986608661866286638664866586668667866886698670867186728673867486758676867786788679868086818682868386848685868686878688868986908691869286938694869586968697869886998700870187028703870487058706870787088709871087118712871387148715871687178718871987208721872287238724872587268727872887298730873187328733873487358736873787388739874087418742874387448745874687478748874987508751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820882188228823882488258826882788288829883088318832883388348835883688378838883988408841884288438844884588468847884888498850885188528853885488558856885788588859886088618862886388648865886688678868886988708871887288738874887588768877887888798880888188828883888488858886888788888889889088918892889388948895889688978898889989008901890289038904890589068907890889098910891189128913891489158916891789188919892089218922892389248925892689278928892989308931893289338934893589368937893889398940894189428943894489458946894789488949895089518952895389548955895689578958895989608961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030903190329033903490359036903790389039904090419042904390449045904690479048904990509051905290539054905590569057905890599060906190629063906490659066906790689069907090719072907390749075907690779078907990809081908290839084908590869087908890899090909190929093909490959096909790989099910091019102910391049105910691079108910991109111911291139114911591169117911891199120912191229123912491259126912791289129913091319132913391349135913691379138913991409141914291439144914591469147914891499150915191529153915491559156915791589159916091619162916391649165916691679168916991709171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240924192429243924492459246924792489249925092519252925392549255925692579258925992609261926292639264926592669267926892699270927192729273927492759276927792789279928092819282928392849285928692879288928992909291929292939294929592969297929892999300930193029303930493059306930793089309931093119312931393149315931693179318931993209321932293239324932593269327932893299330933193329333933493359336933793389339934093419342934393449345934693479348934993509351935293539354935593569357935893599360936193629363936493659366936793689369937093719372937393749375937693779378937993809381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450945194529453945494559456945794589459946094619462946394649465946694679468946994709471947294739474947594769477947894799480948194829483948494859486948794889489949094919492949394949495949694979498949995009501950295039504950595069507950895099510951195129513951495159516951795189519952095219522952395249525952695279528952995309531953295339534953595369537953895399540954195429543954495459546954795489549955095519552955395549555955695579558955995609561956295639564956595669567956895699570957195729573957495759576957795789579958095819582958395849585958695879588958995909591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660966196629663966496659666966796689669967096719672967396749675967696779678967996809681968296839684968596869687968896899690969196929693969496959696969796989699970097019702970397049705970697079708970997109711971297139714971597169717971897199720972197229723972497259726972797289729973097319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792979397949795979697979798979998009801980298039804980598069807980898099810981198129813981498159816981798189819982098219822982398249825982698279828982998309831983298339834983598369837983898399840984198429843984498459846984798489849985098519852985398549855985698579858985998609861986298639864986598669867986898699870987198729873987498759876987798789879988098819882988398849885988698879888988998909891989298939894989598969897989898999900990199029903990499059906990799089909991099119912991399149915991699179918991999209921992299239924992599269927992899299930993199329933993499359936993799389939994099419942994399449945994699479948994999509951995299539954995599569957995899599960996199629963996499659966996799689969997099719972997399749975997699779978997999809981998299839984998599869987998899899990999199929993999499959996999799989999100001000110002100031000410005100061000710008100091001010011100121001310014100151001610017100181001910020100211002210023100241002510026100271002810029100301003110032100331003410035100361003710038100391004010041100421004310044100451004610047100481004910050100511005210053100541005510056100571005810059100601006110062100631006410065100661006710068100691007010071100721007310074100751007610077100781007910080100811008210083100841008510086100871008810089100901009110092100931009410095100961009710098100991010010101101021010310104101051010610107101081010910110101111011210113101141011510116101171011810119101201012110122101231012410125101261012710128101291013010131101321013310134101351013610137101381013910140101411014210143101441014510146101471014810149101501015110152101531015410155101561015710158101591016010161101621016310164101651016610167101681016910170101711017210173101741017510176101771017810179101801018110182101831018410185101861018710188101891019010191101921019310194101951019610197101981019910200102011020210203102041020510206102071020810209102101021110212102131021410215102161021710218102191022010221102221022310224102251022610227102281022910230102311023210233102341023510236102371023810239102401024110242102431024410245102461024710248102491025010251102521025310254102551025610257102581025910260102611026210263102641026510266102671026810269102701027110272102731027410275102761027710278102791028010281102821028310284102851028610287102881028910290102911029210293102941029510296102971029810299103001030110302103031030410305103061030710308103091031010311103121031310314103151031610317103181031910320103211032210323103241032510326103271032810329103301033110332103331033410335103361033710338103391034010341103421034310344103451034610347103481034910350103511035210353103541035510356103571035810359103601036110362103631036410365103661036710368103691037010371103721037310374103751037610377103781037910380103811038210383103841038510386103871038810389103901039110392103931039410395103961039710398103991040010401104021040310404104051040610407104081040910410104111041210413104141041510416104171041810419104201042110422104231042410425104261042710428104291043010431104321043310434104351043610437104381043910440104411044210443104441044510446104471044810449104501045110452104531045410455104561045710458104591046010461104621046310464104651046610467104681046910470104711047210473104741047510476104771047810479104801048110482104831048410485104861048710488104891049010491104921049310494104951049610497104981049910500105011050210503105041050510506105071050810509105101051110512105131051410515105161051710518105191052010521105221052310524105251052610527105281052910530105311053210533105341053510536105371053810539105401054110542105431054410545105461054710548105491055010551105521055310554105551055610557105581055910560105611056210563105641056510566105671056810569105701057110572105731057410575105761057710578105791058010581105821058310584105851058610587105881058910590105911059210593105941059510596105971059810599106001060110602106031060410605106061060710608106091061010611106121061310614106151061610617106181061910620106211062210623106241062510626106271062810629106301063110632106331063410635106361063710638106391064010641106421064310644106451064610647106481064910650106511065210653106541065510656106571065810659106601066110662106631066410665106661066710668106691067010671106721067310674106751067610677106781067910680106811068210683106841068510686106871068810689106901069110692106931069410695106961069710698106991070010701107021070310704107051070610707107081070910710107111071210713107141071510716107171071810719107201072110722107231072410725107261072710728107291073010731107321073310734107351073610737107381073910740107411074210743107441074510746107471074810749107501075110752107531075410755107561075710758107591076010761107621076310764107651076610767107681076910770107711077210773107741077510776107771077810779107801078110782107831078410785107861078710788107891079010791107921079310794107951079610797107981079910800108011080210803108041080510806108071080810809108101081110812108131081410815108161081710818108191082010821108221082310824108251082610827108281082910830108311083210833108341083510836108371083810839108401084110842108431084410845108461084710848108491085010851108521085310854108551085610857108581085910860108611086210863108641086510866108671086810869108701087110872108731087410875108761087710878108791088010881108821088310884108851088610887108881088910890108911089210893108941089510896108971089810899109001090110902109031090410905109061090710908109091091010911109121091310914109151091610917109181091910920109211092210923109241092510926109271092810929109301093110932109331093410935109361093710938109391094010941109421094310944109451094610947109481094910950109511095210953109541095510956109571095810959109601096110962109631096410965109661096710968109691097010971109721097310974109751097610977109781097910980109811098210983109841098510986109871098810989109901099110992109931099410995109961099710998109991100011001110021100311004110051100611007110081100911010110111101211013110141101511016110171101811019110201102111022110231102411025110261102711028110291103011031110321103311034110351103611037110381103911040110411104211043110441104511046110471104811049110501105111052110531105411055110561105711058110591106011061110621106311064110651106611067110681106911070110711107211073110741107511076110771107811079110801108111082110831108411085110861108711088110891109011091110921109311094110951109611097110981109911100111011110211103111041110511106111071110811109111101111111112111131111411115111161111711118111191112011121111221112311124111251112611127111281112911130111311113211133111341113511136111371113811139111401114111142111431114411145111461114711148111491115011151111521115311154111551115611157111581115911160111611116211163111641116511166111671116811169111701117111172111731117411175111761117711178111791118011181111821118311184111851118611187111881118911190111911119211193111941119511196111971119811199112001120111202112031120411205112061120711208112091121011211112121121311214112151121611217112181121911220112211122211223112241122511226112271122811229112301123111232112331123411235112361123711238112391124011241112421124311244112451124611247112481124911250112511125211253112541125511256112571125811259112601126111262112631126411265112661126711268112691127011271112721127311274112751127611277112781127911280112811128211283112841128511286112871128811289112901129111292112931129411295112961129711298112991130011301113021130311304113051130611307113081130911310113111131211313113141131511316113171131811319113201132111322113231132411325113261132711328113291133011331113321133311334113351133611337113381133911340113411134211343113441134511346113471134811349113501135111352113531135411355113561135711358113591136011361113621136311364113651136611367113681136911370113711137211373113741137511376113771137811379113801138111382113831138411385113861138711388113891139011391113921139311394113951139611397113981139911400114011140211403114041140511406114071140811409114101141111412114131141411415114161141711418114191142011421114221142311424114251142611427114281142911430114311143211433114341143511436114371143811439114401144111442114431144411445114461144711448114491145011451114521145311454114551145611457114581145911460114611146211463114641146511466114671146811469114701147111472114731147411475114761147711478114791148011481114821148311484114851148611487114881148911490114911149211493114941149511496114971149811499115001150111502115031150411505115061150711508115091151011511115121151311514115151151611517115181151911520115211152211523115241152511526115271152811529115301153111532115331153411535115361153711538115391154011541115421154311544115451154611547115481154911550115511155211553115541155511556115571155811559115601156111562115631156411565115661156711568115691157011571115721157311574115751157611577115781157911580115811158211583115841158511586115871158811589115901159111592115931159411595115961159711598115991160011601116021160311604116051160611607116081160911610116111161211613116141161511616116171161811619116201162111622116231162411625116261162711628116291163011631116321163311634116351163611637116381163911640116411164211643116441164511646116471164811649116501165111652116531165411655116561165711658116591166011661116621166311664116651166611667116681166911670116711167211673116741167511676116771167811679116801168111682116831168411685116861168711688116891169011691116921169311694116951169611697116981169911700117011170211703117041170511706117071170811709117101171111712117131171411715117161171711718117191172011721117221172311724117251172611727117281172911730117311173211733117341173511736117371173811739117401174111742117431174411745117461174711748117491175011751117521175311754117551175611757117581175911760117611176211763117641176511766117671176811769117701177111772117731177411775117761177711778117791178011781117821178311784117851178611787117881178911790117911179211793117941179511796117971179811799118001180111802118031180411805118061180711808118091181011811118121181311814118151181611817118181181911820118211182211823118241182511826118271182811829118301183111832118331183411835118361183711838118391184011841118421184311844118451184611847118481184911850118511185211853118541185511856118571185811859118601186111862118631186411865118661186711868118691187011871118721187311874118751187611877118781187911880118811188211883118841188511886118871188811889118901189111892118931189411895118961189711898118991190011901119021190311904119051190611907119081190911910119111191211913119141191511916119171191811919119201192111922119231192411925119261192711928119291193011931119321193311934119351193611937119381193911940119411194211943119441194511946119471194811949119501195111952119531195411955119561195711958119591196011961119621196311964119651196611967119681196911970119711197211973119741197511976119771197811979119801198111982119831198411985119861198711988119891199011991119921199311994119951199611997119981199912000120011200212003120041200512006120071200812009120101201112012120131201412015120161201712018120191202012021120221202312024120251202612027120281202912030120311203212033120341203512036120371203812039120401204112042120431204412045120461204712048120491205012051120521205312054120551205612057120581205912060120611206212063120641206512066120671206812069120701207112072120731207412075120761207712078120791208012081120821208312084120851208612087120881208912090120911209212093120941209512096120971209812099121001210112102121031210412105121061210712108121091211012111121121211312114121151211612117121181211912120121211212212123121241212512126121271212812129121301213112132121331213412135121361213712138121391214012141121421214312144121451214612147121481214912150121511215212153121541215512156121571215812159121601216112162121631216412165121661216712168121691217012171121721217312174121751217612177121781217912180121811218212183121841218512186121871218812189121901219112192121931219412195121961219712198121991220012201122021220312204122051220612207122081220912210122111221212213122141221512216122171221812219122201222112222122231222412225122261222712228122291223012231122321223312234122351223612237122381223912240122411224212243122441224512246122471224812249122501225112252122531225412255122561225712258122591226012261122621226312264122651226612267122681226912270122711227212273122741227512276122771227812279122801228112282122831228412285122861228712288122891229012291122921229312294122951229612297122981229912300123011230212303123041230512306123071230812309123101231112312123131231412315123161231712318123191232012321123221232312324123251232612327123281232912330123311233212333123341233512336123371233812339123401234112342123431234412345123461234712348123491235012351123521235312354123551235612357123581235912360123611236212363123641236512366123671236812369123701237112372123731237412375123761237712378123791238012381123821238312384123851238612387123881238912390123911239212393123941239512396123971239812399124001240112402124031240412405124061240712408124091241012411124121241312414124151241612417124181241912420124211242212423124241242512426124271242812429124301243112432124331243412435124361243712438124391244012441124421244312444124451244612447124481244912450124511245212453124541245512456124571245812459124601246112462124631246412465124661246712468124691247012471124721247312474124751247612477124781247912480124811248212483124841248512486124871248812489124901249112492124931249412495124961249712498124991250012501125021250312504125051250612507125081250912510125111251212513125141251512516125171251812519125201252112522125231252412525125261252712528125291253012531125321253312534125351253612537125381253912540125411254212543125441254512546125471254812549125501255112552125531255412555125561255712558125591256012561125621256312564125651256612567125681256912570125711257212573125741257512576125771257812579125801258112582125831258412585125861258712588125891259012591125921259312594125951259612597125981259912600126011260212603126041260512606126071260812609126101261112612126131261412615126161261712618126191262012621126221262312624126251262612627126281262912630126311263212633126341263512636126371263812639126401264112642126431264412645126461264712648126491265012651126521265312654126551265612657126581265912660126611266212663126641266512666126671266812669126701267112672126731267412675126761267712678126791268012681126821268312684126851268612687126881268912690126911269212693126941269512696126971269812699127001270112702127031270412705127061270712708127091271012711127121271312714127151271612717127181271912720127211272212723127241272512726127271272812729127301273112732127331273412735127361273712738127391274012741127421274312744127451274612747127481274912750127511275212753127541275512756127571275812759127601276112762127631276412765127661276712768127691277012771127721277312774127751277612777127781277912780127811278212783127841278512786127871278812789127901279112792127931279412795127961279712798127991280012801128021280312804128051280612807128081280912810128111281212813128141281512816128171281812819128201282112822128231282412825128261282712828128291283012831128321283312834128351283612837128381283912840128411284212843128441284512846128471284812849128501285112852128531285412855128561285712858128591286012861128621286312864128651286612867128681286912870128711287212873128741287512876128771287812879128801288112882128831288412885128861288712888128891289012891128921289312894128951289612897128981289912900129011290212903129041290512906129071290812909129101291112912129131291412915129161291712918129191292012921129221292312924129251292612927129281292912930129311293212933129341293512936129371293812939129401294112942129431294412945129461294712948129491295012951129521295312954129551295612957129581295912960129611296212963129641296512966129671296812969129701297112972129731297412975129761297712978129791298012981129821298312984129851298612987129881298912990129911299212993129941299512996129971299812999130001300113002130031300413005130061300713008130091301013011130121301313014130151301613017130181301913020130211302213023130241302513026130271302813029130301303113032130331303413035130361303713038130391304013041130421304313044130451304613047130481304913050130511305213053130541305513056130571305813059130601306113062130631306413065130661306713068130691307013071130721307313074130751307613077130781307913080130811308213083130841308513086130871308813089130901309113092130931309413095130961309713098130991310013101131021310313104131051310613107131081310913110131111311213113131141311513116131171311813119131201312113122131231312413125131261312713128131291313013131131321313313134131351313613137131381313913140131411314213143131441314513146131471314813149131501315113152131531315413155131561315713158131591316013161131621316313164131651316613167131681316913170131711317213173131741317513176131771317813179131801318113182131831318413185131861318713188131891319013191131921319313194131951319613197131981319913200132011320213203132041320513206132071320813209132101321113212132131321413215132161321713218132191322013221132221322313224132251322613227132281322913230132311323213233132341323513236132371323813239132401324113242132431324413245132461324713248132491325013251132521325313254132551325613257132581325913260132611326213263132641326513266132671326813269132701327113272132731327413275132761327713278132791328013281132821328313284132851328613287132881328913290132911329213293132941329513296132971329813299133001330113302133031330413305133061330713308133091331013311133121331313314133151331613317133181331913320133211332213323133241332513326133271332813329133301333113332133331333413335133361333713338133391334013341133421334313344133451334613347133481334913350133511335213353133541335513356133571335813359133601336113362133631336413365133661336713368133691337013371133721337313374133751337613377133781337913380133811338213383133841338513386133871338813389133901339113392133931339413395133961339713398133991340013401134021340313404134051340613407134081340913410134111341213413134141341513416134171341813419134201342113422134231342413425134261342713428134291343013431134321343313434134351343613437134381343913440134411344213443134441344513446134471344813449134501345113452134531345413455134561345713458134591346013461134621346313464134651346613467134681346913470134711347213473134741347513476134771347813479134801348113482134831348413485134861348713488134891349013491134921349313494134951349613497134981349913500135011350213503135041350513506135071350813509135101351113512135131351413515135161351713518135191352013521135221352313524135251352613527135281352913530135311353213533135341353513536135371353813539135401354113542135431354413545135461354713548135491355013551135521355313554135551355613557135581355913560135611356213563135641356513566135671356813569135701357113572135731357413575135761357713578135791358013581135821358313584135851358613587135881358913590135911359213593135941359513596135971359813599136001360113602136031360413605136061360713608136091361013611136121361313614136151361613617136181361913620136211362213623136241362513626136271362813629136301363113632136331363413635136361363713638136391364013641136421364313644136451364613647136481364913650136511365213653136541365513656136571365813659136601366113662136631366413665136661366713668136691367013671136721367313674136751367613677136781367913680136811368213683136841368513686136871368813689136901369113692136931369413695136961369713698136991370013701137021370313704137051370613707137081370913710137111371213713137141371513716137171371813719137201372113722137231372413725137261372713728137291373013731137321373313734137351373613737137381373913740137411374213743137441374513746137471374813749137501375113752137531375413755137561375713758137591376013761137621376313764137651376613767137681376913770137711377213773137741377513776137771377813779137801378113782137831378413785137861378713788137891379013791137921379313794137951379613797137981379913800138011380213803138041380513806138071380813809138101381113812138131381413815138161381713818138191382013821138221382313824138251382613827138281382913830138311383213833138341383513836138371383813839138401384113842138431384413845138461384713848138491385013851138521385313854138551385613857138581385913860138611386213863138641386513866138671386813869138701387113872138731387413875138761387713878138791388013881138821388313884138851388613887138881388913890138911389213893138941389513896138971389813899139001390113902139031390413905139061390713908139091391013911139121391313914139151391613917139181391913920139211392213923139241392513926139271392813929139301393113932139331393413935139361393713938139391394013941139421394313944139451394613947139481394913950139511395213953139541395513956139571395813959139601396113962139631396413965139661396713968139691397013971139721397313974139751397613977139781397913980139811398213983139841398513986139871398813989139901399113992139931399413995139961399713998139991400014001140021400314004140051400614007140081400914010140111401214013140141401514016140171401814019140201402114022140231402414025140261402714028140291403014031140321403314034140351403614037140381403914040140411404214043140441404514046140471404814049140501405114052140531405414055140561405714058140591406014061140621406314064140651406614067140681406914070140711407214073140741407514076140771407814079140801408114082140831408414085140861408714088140891409014091140921409314094140951409614097140981409914100141011410214103141041410514106141071410814109141101411114112141131411414115141161411714118141191412014121141221412314124141251412614127141281412914130141311413214133141341413514136141371413814139141401414114142141431414414145141461414714148141491415014151141521415314154141551415614157141581415914160141611416214163141641416514166141671416814169141701417114172141731417414175141761417714178141791418014181141821418314184141851418614187141881418914190141911419214193141941419514196141971419814199142001420114202142031420414205142061420714208142091421014211142121421314214142151421614217142181421914220142211422214223142241422514226142271422814229142301423114232142331423414235142361423714238142391424014241142421424314244142451424614247142481424914250142511425214253142541425514256142571425814259142601426114262142631426414265142661426714268142691427014271142721427314274142751427614277142781427914280142811428214283142841428514286142871428814289142901429114292142931429414295142961429714298142991430014301143021430314304143051430614307143081430914310143111431214313143141431514316143171431814319143201432114322143231432414325143261432714328143291433014331143321433314334143351433614337143381433914340143411434214343143441434514346143471434814349143501435114352143531435414355143561435714358143591436014361143621436314364143651436614367143681436914370143711437214373143741437514376143771437814379143801438114382143831438414385143861438714388143891439014391143921439314394143951439614397143981439914400144011440214403144041440514406144071440814409144101441114412144131441414415144161441714418144191442014421144221442314424144251442614427144281442914430144311443214433144341443514436144371443814439144401444114442144431444414445144461444714448144491445014451144521445314454144551445614457144581445914460144611446214463144641446514466144671446814469144701447114472144731447414475144761447714478144791448014481144821448314484144851448614487144881448914490144911449214493144941449514496144971449814499145001450114502145031450414505145061450714508145091451014511145121451314514145151451614517145181451914520145211452214523145241452514526145271452814529145301453114532145331453414535145361453714538145391454014541145421454314544145451454614547145481454914550145511455214553145541455514556145571455814559145601456114562145631456414565145661456714568145691457014571145721457314574145751457614577145781457914580145811458214583145841458514586145871458814589145901459114592145931459414595145961459714598145991460014601146021460314604146051460614607146081460914610146111461214613146141461514616146171461814619146201462114622146231462414625146261462714628146291463014631146321463314634146351463614637146381463914640146411464214643146441464514646146471464814649146501465114652146531465414655146561465714658146591466014661146621466314664146651466614667146681466914670146711467214673146741467514676146771467814679146801468114682146831468414685146861468714688146891469014691146921469314694146951469614697146981469914700147011470214703147041470514706147071470814709147101471114712147131471414715147161471714718147191472014721147221472314724147251472614727147281472914730147311473214733147341473514736147371473814739147401474114742147431474414745147461474714748147491475014751147521475314754147551475614757147581475914760147611476214763147641476514766147671476814769147701477114772147731477414775147761477714778147791478014781147821478314784147851478614787147881478914790147911479214793147941479514796147971479814799148001480114802148031480414805148061480714808148091481014811148121481314814148151481614817148181481914820148211482214823148241482514826148271482814829148301483114832148331483414835148361483714838148391484014841148421484314844148451484614847148481484914850148511485214853148541485514856148571485814859148601486114862148631486414865148661486714868148691487014871148721487314874148751487614877148781487914880148811488214883148841488514886148871488814889148901489114892148931489414895148961489714898148991490014901149021490314904149051490614907149081490914910149111491214913149141491514916149171491814919149201492114922149231492414925149261492714928149291493014931149321493314934149351493614937149381493914940149411494214943149441494514946149471494814949149501495114952149531495414955149561495714958149591496014961149621496314964149651496614967149681496914970149711497214973149741497514976149771497814979149801498114982149831498414985149861498714988149891499014991149921499314994149951499614997149981499915000150011500215003150041500515006150071500815009150101501115012150131501415015150161501715018150191502015021150221502315024150251502615027150281502915030150311503215033150341503515036150371503815039150401504115042150431504415045150461504715048150491505015051150521505315054150551505615057150581505915060150611506215063150641506515066150671506815069150701507115072150731507415075150761507715078150791508015081150821508315084150851508615087150881508915090150911509215093150941509515096150971509815099151001510115102151031510415105151061510715108151091511015111151121511315114151151511615117151181511915120151211512215123151241512515126151271512815129151301513115132151331513415135151361513715138151391514015141151421514315144151451514615147151481514915150151511515215153151541515515156151571515815159151601516115162151631516415165151661516715168151691517015171151721517315174151751517615177151781517915180151811518215183151841518515186151871518815189151901519115192151931519415195151961519715198151991520015201152021520315204152051520615207152081520915210152111521215213152141521515216152171521815219152201522115222152231522415225152261522715228152291523015231152321523315234152351523615237152381523915240152411524215243152441524515246152471524815249152501525115252152531525415255152561525715258152591526015261152621526315264152651526615267152681526915270152711527215273152741527515276152771527815279152801528115282152831528415285152861528715288152891529015291152921529315294152951529615297152981529915300153011530215303153041530515306153071530815309153101531115312153131531415315153161531715318153191532015321153221532315324153251532615327153281532915330153311533215333153341533515336153371533815339153401534115342153431534415345153461534715348153491535015351153521535315354153551535615357153581535915360153611536215363153641536515366153671536815369153701537115372153731537415375153761537715378153791538015381153821538315384153851538615387153881538915390153911539215393153941539515396153971539815399154001540115402154031540415405154061540715408154091541015411154121541315414154151541615417154181541915420154211542215423154241542515426154271542815429154301543115432154331543415435154361543715438154391544015441154421544315444154451544615447154481544915450154511545215453154541545515456154571545815459154601546115462154631546415465154661546715468154691547015471154721547315474154751547615477154781547915480154811548215483154841548515486154871548815489154901549115492154931549415495154961549715498154991550015501155021550315504155051550615507155081550915510155111551215513155141551515516155171551815519155201552115522155231552415525155261552715528155291553015531155321553315534155351553615537155381553915540155411554215543155441554515546155471554815549155501555115552155531555415555155561555715558155591556015561155621556315564155651556615567155681556915570155711557215573155741557515576155771557815579155801558115582155831558415585155861558715588155891559015591155921559315594155951559615597155981559915600156011560215603156041560515606156071560815609156101561115612156131561415615156161561715618156191562015621156221562315624156251562615627156281562915630156311563215633156341563515636156371563815639156401564115642156431564415645156461564715648156491565015651156521565315654156551565615657156581565915660156611566215663156641566515666156671566815669156701567115672156731567415675156761567715678156791568015681156821568315684156851568615687156881568915690156911569215693156941569515696156971569815699157001570115702157031570415705157061570715708157091571015711157121571315714157151571615717157181571915720157211572215723157241572515726157271572815729157301573115732157331573415735157361573715738157391574015741157421574315744157451574615747157481574915750157511575215753157541575515756157571575815759157601576115762157631576415765157661576715768157691577015771157721577315774157751577615777157781577915780157811578215783157841578515786157871578815789157901579115792157931579415795157961579715798157991580015801158021580315804158051580615807158081580915810158111581215813158141581515816158171581815819158201582115822158231582415825158261582715828158291583015831158321583315834158351583615837158381583915840158411584215843158441584515846158471584815849158501585115852158531585415855158561585715858158591586015861158621586315864158651586615867158681586915870158711587215873158741587515876158771587815879158801588115882158831588415885158861588715888158891589015891158921589315894158951589615897158981589915900159011590215903159041590515906159071590815909159101591115912159131591415915159161591715918159191592015921159221592315924159251592615927159281592915930159311593215933159341593515936159371593815939159401594115942159431594415945159461594715948159491595015951159521595315954159551595615957159581595915960159611596215963159641596515966159671596815969159701597115972159731597415975159761597715978159791598015981159821598315984159851598615987159881598915990159911599215993159941599515996159971599815999160001600116002160031600416005160061600716008160091601016011160121601316014160151601616017160181601916020160211602216023160241602516026160271602816029160301603116032160331603416035160361603716038160391604016041160421604316044160451604616047160481604916050160511605216053160541605516056160571605816059160601606116062160631606416065160661606716068160691607016071160721607316074160751607616077160781607916080160811608216083160841608516086160871608816089160901609116092160931609416095160961609716098160991610016101161021610316104161051610616107161081610916110161111611216113161141611516116161171611816119161201612116122161231612416125161261612716128161291613016131161321613316134161351613616137161381613916140161411614216143161441614516146161471614816149161501615116152161531615416155161561615716158161591616016161161621616316164161651616616167161681616916170161711617216173161741617516176161771617816179161801618116182161831618416185161861618716188161891619016191161921619316194161951619616197161981619916200162011620216203162041620516206162071620816209162101621116212162131621416215162161621716218162191622016221162221622316224162251622616227162281622916230162311623216233162341623516236162371623816239162401624116242162431624416245162461624716248162491625016251162521625316254162551625616257162581625916260162611626216263162641626516266162671626816269162701627116272162731627416275162761627716278162791628016281162821628316284162851628616287162881628916290162911629216293162941629516296162971629816299163001630116302163031630416305163061630716308163091631016311163121631316314163151631616317163181631916320163211632216323163241632516326163271632816329163301633116332163331633416335163361633716338163391634016341163421634316344163451634616347163481634916350163511635216353163541635516356163571635816359163601636116362163631636416365163661636716368163691637016371163721637316374163751637616377163781637916380163811638216383163841638516386163871638816389163901639116392163931639416395163961639716398163991640016401164021640316404164051640616407164081640916410164111641216413164141641516416164171641816419164201642116422164231642416425164261642716428164291643016431164321643316434164351643616437164381643916440164411644216443164441644516446164471644816449164501645116452164531645416455164561645716458164591646016461164621646316464164651646616467164681646916470164711647216473164741647516476164771647816479164801648116482164831648416485164861648716488164891649016491164921649316494164951649616497164981649916500165011650216503165041650516506165071650816509165101651116512165131651416515165161651716518165191652016521165221652316524165251652616527165281652916530165311653216533165341653516536165371653816539165401654116542165431654416545165461654716548165491655016551165521655316554165551655616557165581655916560165611656216563165641656516566165671656816569165701657116572165731657416575165761657716578165791658016581165821658316584165851658616587165881658916590165911659216593165941659516596165971659816599166001660116602166031660416605166061660716608166091661016611166121661316614166151661616617166181661916620166211662216623166241662516626166271662816629166301663116632166331663416635166361663716638166391664016641166421664316644166451664616647166481664916650166511665216653166541665516656166571665816659166601666116662166631666416665166661666716668166691667016671166721667316674166751667616677166781667916680166811668216683166841668516686166871668816689166901669116692166931669416695166961669716698166991670016701167021670316704167051670616707167081670916710167111671216713167141671516716167171671816719167201672116722167231672416725167261672716728167291673016731167321673316734167351673616737167381673916740167411674216743167441674516746167471674816749167501675116752167531675416755167561675716758167591676016761167621676316764167651676616767167681676916770167711677216773167741677516776167771677816779167801678116782167831678416785167861678716788167891679016791167921679316794167951679616797167981679916800168011680216803168041680516806168071680816809168101681116812168131681416815168161681716818168191682016821168221682316824168251682616827168281682916830168311683216833168341683516836168371683816839168401684116842168431684416845168461684716848168491685016851168521685316854168551685616857168581685916860168611686216863168641686516866168671686816869168701687116872168731687416875168761687716878168791688016881168821688316884168851688616887168881688916890168911689216893168941689516896168971689816899169001690116902169031690416905169061690716908169091691016911169121691316914169151691616917169181691916920169211692216923169241692516926169271692816929169301693116932169331693416935169361693716938169391694016941169421694316944169451694616947169481694916950169511695216953169541695516956169571695816959169601696116962169631696416965169661696716968169691697016971169721697316974169751697616977169781697916980169811698216983169841698516986169871698816989169901699116992169931699416995169961699716998169991700017001170021700317004170051700617007170081700917010170111701217013170141701517016170171701817019170201702117022170231702417025170261702717028170291703017031170321703317034170351703617037170381703917040170411704217043170441704517046170471704817049170501705117052170531705417055170561705717058170591706017061170621706317064170651706617067170681706917070170711707217073170741707517076170771707817079170801708117082170831708417085170861708717088170891709017091170921709317094170951709617097170981709917100171011710217103171041710517106171071710817109171101711117112171131711417115171161711717118171191712017121171221712317124171251712617127171281712917130171311713217133171341713517136171371713817139171401714117142171431714417145171461714717148171491715017151171521715317154171551715617157171581715917160171611716217163171641716517166171671716817169171701717117172171731717417175171761717717178171791718017181171821718317184171851718617187171881718917190171911719217193171941719517196171971719817199172001720117202172031720417205172061720717208172091721017211172121721317214172151721617217172181721917220172211722217223172241722517226172271722817229172301723117232172331723417235172361723717238172391724017241172421724317244172451724617247172481724917250172511725217253172541725517256172571725817259172601726117262172631726417265172661726717268172691727017271172721727317274172751727617277172781727917280172811728217283172841728517286172871728817289172901729117292172931729417295172961729717298172991730017301173021730317304173051730617307173081730917310173111731217313173141731517316173171731817319173201732117322173231732417325173261732717328173291733017331173321733317334173351733617337173381733917340173411734217343173441734517346173471734817349173501735117352173531735417355173561735717358173591736017361173621736317364173651736617367173681736917370173711737217373173741737517376173771737817379173801738117382173831738417385173861738717388173891739017391173921739317394173951739617397173981739917400174011740217403174041740517406174071740817409174101741117412174131741417415174161741717418174191742017421174221742317424174251742617427174281742917430174311743217433174341743517436174371743817439174401744117442174431744417445174461744717448174491745017451174521745317454174551745617457174581745917460174611746217463174641746517466174671746817469174701747117472174731747417475174761747717478174791748017481174821748317484174851748617487174881748917490174911749217493174941749517496174971749817499175001750117502175031750417505175061750717508175091751017511175121751317514175151751617517175181751917520175211752217523175241752517526175271752817529175301753117532175331753417535175361753717538175391754017541175421754317544175451754617547175481754917550175511755217553175541755517556175571755817559175601756117562175631756417565175661756717568175691757017571175721757317574175751757617577175781757917580175811758217583175841758517586175871758817589175901759117592175931759417595175961759717598175991760017601176021760317604176051760617607176081760917610176111761217613176141761517616176171761817619176201762117622176231762417625176261762717628176291763017631176321763317634176351763617637176381763917640176411764217643176441764517646176471764817649176501765117652176531765417655176561765717658176591766017661176621766317664176651766617667176681766917670176711767217673176741767517676176771767817679176801768117682176831768417685176861768717688176891769017691176921769317694176951769617697176981769917700177011770217703177041770517706177071770817709177101771117712177131771417715177161771717718177191772017721177221772317724177251772617727177281772917730177311773217733177341773517736177371773817739177401774117742177431774417745177461774717748177491775017751177521775317754177551775617757177581775917760177611776217763177641776517766177671776817769177701777117772177731777417775177761777717778177791778017781177821778317784177851778617787177881778917790177911779217793177941779517796177971779817799178001780117802178031780417805178061780717808178091781017811178121781317814178151781617817178181781917820178211782217823178241782517826178271782817829178301783117832178331783417835178361783717838178391784017841178421784317844178451784617847178481784917850178511785217853178541785517856178571785817859178601786117862178631786417865178661786717868178691787017871178721787317874178751787617877178781787917880178811788217883178841788517886178871788817889178901789117892178931789417895178961789717898178991790017901179021790317904179051790617907179081790917910179111791217913179141791517916179171791817919179201792117922179231792417925179261792717928179291793017931179321793317934179351793617937179381793917940179411794217943179441794517946179471794817949179501795117952179531795417955179561795717958179591796017961179621796317964179651796617967179681796917970179711797217973179741797517976179771797817979179801798117982179831798417985179861798717988179891799017991179921799317994179951799617997179981799918000180011800218003180041800518006180071800818009180101801118012180131801418015180161801718018180191802018021180221802318024180251802618027180281802918030180311803218033180341803518036180371803818039180401804118042180431804418045180461804718048180491805018051180521805318054180551805618057180581805918060180611806218063180641806518066180671806818069180701807118072180731807418075180761807718078180791808018081180821808318084180851808618087180881808918090180911809218093180941809518096180971809818099181001810118102181031810418105181061810718108181091811018111181121811318114181151811618117181181811918120181211812218123181241812518126181271812818129181301813118132181331813418135181361813718138181391814018141181421814318144181451814618147181481814918150181511815218153181541815518156181571815818159181601816118162181631816418165181661816718168181691817018171181721817318174181751817618177181781817918180181811818218183181841818518186181871818818189181901819118192181931819418195181961819718198181991820018201182021820318204182051820618207182081820918210182111821218213182141821518216182171821818219182201822118222182231822418225182261822718228182291823018231182321823318234182351823618237182381823918240182411824218243182441824518246182471824818249182501825118252182531825418255182561825718258182591826018261182621826318264182651826618267182681826918270182711827218273182741827518276182771827818279182801828118282182831828418285182861828718288182891829018291182921829318294182951829618297182981829918300183011830218303183041830518306183071830818309183101831118312183131831418315183161831718318183191832018321183221832318324183251832618327183281832918330183311833218333183341833518336183371833818339183401834118342183431834418345183461834718348183491835018351183521835318354183551835618357183581835918360183611836218363183641836518366183671836818369183701837118372183731837418375183761837718378183791838018381183821838318384183851838618387183881838918390183911839218393183941839518396183971839818399184001840118402184031840418405184061840718408184091841018411184121841318414184151841618417184181841918420184211842218423184241842518426184271842818429184301843118432184331843418435184361843718438184391844018441184421844318444184451844618447184481844918450184511845218453184541845518456184571845818459184601846118462184631846418465184661846718468184691847018471184721847318474184751847618477184781847918480184811848218483184841848518486184871848818489184901849118492184931849418495184961849718498184991850018501185021850318504185051850618507185081850918510185111851218513185141851518516185171851818519185201852118522185231852418525185261852718528185291853018531185321853318534185351853618537185381853918540185411854218543185441854518546185471854818549185501855118552185531855418555185561855718558185591856018561185621856318564185651856618567185681856918570185711857218573185741857518576185771857818579185801858118582185831858418585185861858718588185891859018591185921859318594185951859618597185981859918600186011860218603186041860518606186071860818609186101861118612186131861418615186161861718618186191862018621186221862318624186251862618627186281862918630186311863218633186341863518636186371863818639186401864118642186431864418645186461864718648186491865018651186521865318654186551865618657186581865918660186611866218663186641866518666186671866818669186701867118672186731867418675186761867718678186791868018681186821868318684186851868618687186881868918690186911869218693186941869518696186971869818699187001870118702187031870418705187061870718708187091871018711187121871318714187151871618717187181871918720187211872218723187241872518726187271872818729187301873118732187331873418735187361873718738187391874018741187421874318744187451874618747187481874918750187511875218753187541875518756187571875818759187601876118762187631876418765187661876718768187691877018771187721877318774187751877618777187781877918780187811878218783187841878518786187871878818789187901879118792187931879418795187961879718798187991880018801188021880318804188051880618807188081880918810188111881218813188141881518816188171881818819188201882118822188231882418825188261882718828188291883018831188321883318834188351883618837188381883918840188411884218843188441884518846188471884818849188501885118852188531885418855188561885718858188591886018861188621886318864188651886618867188681886918870188711887218873188741887518876188771887818879188801888118882188831888418885188861888718888188891889018891188921889318894188951889618897188981889918900189011890218903189041890518906189071890818909189101891118912189131891418915189161891718918189191892018921189221892318924189251892618927189281892918930189311893218933189341893518936189371893818939189401894118942189431894418945189461894718948189491895018951189521895318954189551895618957189581895918960189611896218963189641896518966189671896818969189701897118972189731897418975189761897718978189791898018981189821898318984189851898618987189881898918990189911899218993189941899518996189971899818999190001900119002190031900419005190061900719008190091901019011190121901319014190151901619017190181901919020190211902219023190241902519026190271902819029190301903119032190331903419035190361903719038190391904019041190421904319044190451904619047190481904919050190511905219053190541905519056190571905819059190601906119062190631906419065190661906719068190691907019071190721907319074190751907619077190781907919080190811908219083190841908519086190871908819089190901909119092190931909419095190961909719098190991910019101191021910319104191051910619107191081910919110191111911219113191141911519116191171911819119191201912119122191231912419125191261912719128191291913019131191321913319134191351913619137191381913919140191411914219143191441914519146191471914819149191501915119152191531915419155191561915719158191591916019161191621916319164191651916619167191681916919170191711917219173191741917519176191771917819179191801918119182191831918419185191861918719188191891919019191191921919319194191951919619197191981919919200192011920219203192041920519206192071920819209192101921119212192131921419215192161921719218192191922019221192221922319224192251922619227192281922919230192311923219233192341923519236192371923819239192401924119242192431924419245192461924719248192491925019251192521925319254192551925619257192581925919260192611926219263192641926519266192671926819269192701927119272192731927419275192761927719278192791928019281192821928319284192851928619287192881928919290192911929219293192941929519296192971929819299193001930119302193031930419305193061930719308193091931019311193121931319314193151931619317193181931919320193211932219323193241932519326193271932819329193301933119332193331933419335193361933719338193391934019341193421934319344193451934619347193481934919350193511935219353193541935519356193571935819359193601936119362193631936419365193661936719368193691937019371193721937319374193751937619377193781937919380193811938219383193841938519386193871938819389193901939119392193931939419395193961939719398193991940019401194021940319404194051940619407194081940919410194111941219413194141941519416194171941819419194201942119422194231942419425194261942719428194291943019431194321943319434194351943619437194381943919440194411944219443194441944519446194471944819449194501945119452194531945419455194561945719458194591946019461194621946319464194651946619467194681946919470194711947219473194741947519476194771947819479194801948119482194831948419485194861948719488194891949019491194921949319494194951949619497194981949919500195011950219503195041950519506195071950819509195101951119512195131951419515195161951719518195191952019521195221952319524195251952619527195281952919530195311953219533195341953519536195371953819539195401954119542195431954419545195461954719548195491955019551195521955319554195551955619557195581955919560195611956219563195641956519566195671956819569195701957119572195731957419575195761957719578195791958019581195821958319584195851958619587195881958919590195911959219593195941959519596195971959819599196001960119602196031960419605196061960719608196091961019611196121961319614196151961619617196181961919620196211962219623196241962519626196271962819629196301963119632196331963419635196361963719638196391964019641196421964319644196451964619647196481964919650196511965219653196541965519656196571965819659196601966119662196631966419665196661966719668196691967019671196721967319674196751967619677196781967919680196811968219683196841968519686196871968819689196901969119692196931969419695196961969719698196991970019701197021970319704197051970619707197081970919710197111971219713197141971519716197171971819719197201972119722197231972419725197261972719728197291973019731197321973319734197351973619737197381973919740197411974219743197441974519746197471974819749197501975119752197531975419755197561975719758197591976019761197621976319764197651976619767197681976919770197711977219773197741977519776197771977819779197801978119782197831978419785197861978719788197891979019791197921979319794197951979619797197981979919800198011980219803198041980519806198071980819809198101981119812198131981419815198161981719818198191982019821198221982319824198251982619827198281982919830198311983219833198341983519836198371983819839198401984119842198431984419845198461984719848198491985019851198521985319854198551985619857198581985919860198611986219863198641986519866198671986819869198701987119872198731987419875198761987719878198791988019881198821988319884198851988619887198881988919890198911989219893198941989519896198971989819899199001990119902199031990419905199061990719908199091991019911199121991319914199151991619917199181991919920199211992219923199241992519926199271992819929199301993119932199331993419935199361993719938199391994019941199421994319944199451994619947199481994919950199511995219953199541995519956199571995819959199601996119962199631996419965199661996719968199691997019971199721997319974199751997619977199781997919980199811998219983199841998519986199871998819989199901999119992199931999419995199961999719998199992000020001200022000320004200052000620007200082000920010200112001220013200142001520016200172001820019200202002120022200232002420025200262002720028200292003020031200322003320034200352003620037200382003920040200412004220043200442004520046200472004820049200502005120052200532005420055200562005720058200592006020061200622006320064200652006620067200682006920070200712007220073200742007520076200772007820079200802008120082200832008420085200862008720088200892009020091200922009320094200952009620097200982009920100201012010220103201042010520106201072010820109201102011120112201132011420115201162011720118201192012020121201222012320124201252012620127201282012920130201312013220133201342013520136201372013820139201402014120142201432014420145201462014720148201492015020151201522015320154201552015620157201582015920160201612016220163201642016520166201672016820169201702017120172201732017420175201762017720178201792018020181201822018320184201852018620187201882018920190201912019220193201942019520196201972019820199202002020120202202032020420205202062020720208202092021020211202122021320214202152021620217202182021920220202212022220223202242022520226202272022820229202302023120232202332023420235202362023720238202392024020241202422024320244202452024620247202482024920250202512025220253202542025520256202572025820259202602026120262202632026420265202662026720268202692027020271202722027320274202752027620277202782027920280202812028220283202842028520286202872028820289202902029120292202932029420295202962029720298202992030020301203022030320304203052030620307203082030920310203112031220313203142031520316203172031820319203202032120322203232032420325203262032720328203292033020331203322033320334203352033620337203382033920340203412034220343203442034520346203472034820349203502035120352203532035420355203562035720358203592036020361203622036320364203652036620367203682036920370203712037220373203742037520376203772037820379203802038120382203832038420385203862038720388203892039020391203922039320394203952039620397203982039920400204012040220403204042040520406204072040820409204102041120412204132041420415204162041720418204192042020421204222042320424204252042620427204282042920430204312043220433204342043520436204372043820439204402044120442204432044420445204462044720448204492045020451204522045320454204552045620457204582045920460204612046220463204642046520466204672046820469204702047120472204732047420475204762047720478204792048020481204822048320484204852048620487204882048920490204912049220493204942049520496204972049820499205002050120502205032050420505205062050720508205092051020511205122051320514205152051620517205182051920520205212052220523205242052520526205272052820529205302053120532205332053420535205362053720538205392054020541205422054320544205452054620547205482054920550205512055220553205542055520556205572055820559205602056120562205632056420565205662056720568205692057020571205722057320574205752057620577205782057920580205812058220583205842058520586205872058820589205902059120592205932059420595205962059720598205992060020601206022060320604206052060620607206082060920610206112061220613206142061520616206172061820619206202062120622206232062420625206262062720628206292063020631206322063320634206352063620637206382063920640206412064220643206442064520646206472064820649206502065120652206532065420655206562065720658206592066020661206622066320664206652066620667206682066920670206712067220673206742067520676206772067820679206802068120682206832068420685206862068720688206892069020691206922069320694206952069620697206982069920700207012070220703207042070520706207072070820709207102071120712207132071420715207162071720718207192072020721207222072320724207252072620727207282072920730207312073220733207342073520736207372073820739207402074120742207432074420745207462074720748207492075020751207522075320754207552075620757207582075920760207612076220763207642076520766207672076820769207702077120772207732077420775207762077720778207792078020781207822078320784207852078620787207882078920790207912079220793207942079520796207972079820799208002080120802208032080420805208062080720808208092081020811208122081320814208152081620817208182081920820208212082220823208242082520826208272082820829208302083120832208332083420835208362083720838208392084020841208422084320844208452084620847208482084920850208512085220853208542085520856208572085820859208602086120862208632086420865208662086720868208692087020871208722087320874208752087620877208782087920880208812088220883208842088520886208872088820889208902089120892208932089420895208962089720898208992090020901209022090320904209052090620907209082090920910209112091220913209142091520916209172091820919209202092120922209232092420925209262092720928209292093020931209322093320934209352093620937209382093920940209412094220943209442094520946209472094820949209502095120952209532095420955209562095720958209592096020961209622096320964209652096620967209682096920970209712097220973209742097520976209772097820979209802098120982209832098420985209862098720988209892099020991209922099320994209952099620997209982099921000210012100221003210042100521006210072100821009210102101121012210132101421015210162101721018210192102021021210222102321024210252102621027210282102921030210312103221033210342103521036210372103821039210402104121042210432104421045210462104721048210492105021051210522105321054210552105621057210582105921060210612106221063210642106521066210672106821069210702107121072210732107421075210762107721078210792108021081210822108321084210852108621087210882108921090210912109221093210942109521096210972109821099211002110121102211032110421105
  1. // ==ClosureCompiler==
  2. // @compilation_level SIMPLE_OPTIMIZATIONS
  3. /**
  4. * @license jqGrid 4.15.6-pre - free jqGrid: https://github.com/free-jqgrid/jqGrid
  5. * Copyright (c) 2008-2014, Tony Tomov, tony@trirand.com
  6. * Copyright (c) 2014-2018, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  7. * Dual licensed under the MIT and GPL licenses
  8. * http://www.opensource.org/licenses/mit-license.php
  9. * http://www.gnu.org/licenses/gpl-2.0.html
  10. * Date: 2018-10-08
  11. */
  12. //jsHint options
  13. /*jshint eqnull:true */
  14. /*jslint browser: true, evil: true, devel: true, white: true */
  15. /*global jQuery, define, HTMLElement, HTMLTableRowElement, module, require */
  16. (function (global, factory) {
  17. "use strict";
  18. if (typeof define === "function" && define.amd) {
  19. // AMD. Register as an anonymous module.
  20. //console.log("grid.base AMD");
  21. define([
  22. "jquery"
  23. ], function ($) {
  24. //console.log("grid.base AMD: define callback");
  25. return factory($, global.document);
  26. });
  27. } else if (typeof module === "object" && module.exports) {
  28. // Node/CommonJS
  29. //console.log("grid.base CommonJS");
  30. module.exports = function (root, $) {
  31. //console.log("grid.base CommonJS: in module.exports");
  32. if (!root) {
  33. root = window;
  34. }
  35. //console.log("grid.base CommonJS: before require('jquery')");
  36. if ($ === undefined) {
  37. // require("jquery") returns a factory that requires window to
  38. // build a jQuery instance, we normalize how we use modules
  39. // that require this pattern but the window provided is a noop
  40. // if it's defined (how jquery works)
  41. $ = typeof window !== "undefined" ?
  42. require("jquery") :
  43. require("jquery")(root);
  44. }
  45. //global.jQuery = $;
  46. //root.jQuery = $;
  47. //console.log("grid.base CommonJS: before factory");
  48. factory($, root.document);
  49. return $;
  50. };
  51. } else {
  52. // Browser globals
  53. //console.log("grid.base Browser: before factory");
  54. factory(jQuery, global.document);
  55. }
  56. }(typeof window !== "undefined" ? window : this, function ($, document) {
  57. "use strict";
  58. // begin module grid.base
  59. /** @const */
  60. var englishLanguageDefaults = {
  61. name: "English (United States)",
  62. nameEnglish: "English (United States)",
  63. isRTL: false,
  64. defaults: {
  65. recordtext: "View {0} - {1} of {2}",
  66. emptyrecords: "No records to view",
  67. loadtext: "Loading...",
  68. pgtext: "Page {0} of {1}",
  69. pgfirst: "First Page",
  70. pglast: "Last Page",
  71. pgnext: "Next Page",
  72. pgprev: "Previous Page",
  73. pgrecs: "Records per Page",
  74. showhide: "Toggle Expand Collapse Grid",
  75. savetext: "Saving..."
  76. },
  77. search: {
  78. caption: "Search...",
  79. Find: "Find",
  80. Reset: "Reset",
  81. odata: [
  82. { oper: "eq", text: "equal" },
  83. { oper: "ne", text: "not equal" },
  84. { oper: "lt", text: "less" },
  85. { oper: "le", text: "less or equal" },
  86. { oper: "gt", text: "greater" },
  87. { oper: "ge", text: "greater or equal" },
  88. { oper: "bw", text: "begins with" },
  89. { oper: "bn", text: "does not begin with" },
  90. { oper: "in", text: "is in" },
  91. { oper: "ni", text: "is not in" },
  92. { oper: "ew", text: "ends with" },
  93. { oper: "en", text: "does not end with" },
  94. { oper: "cn", text: "contains" },
  95. { oper: "nc", text: "does not contain" },
  96. { oper: "nu", text: "is null" },
  97. { oper: "nn", text: "is not null" }
  98. ],
  99. groupOps: [
  100. { op: "AND", text: "all" },
  101. { op: "OR", text: "any" }
  102. ],
  103. addGroupTitle: "Add subgroup",
  104. deleteGroupTitle: "Delete group",
  105. addRuleTitle: "Add rule",
  106. deleteRuleTitle: "Delete rule",
  107. operandTitle: "Click to select search operation.",
  108. resetTitle: "Reset Search Value"
  109. },
  110. edit: {
  111. addCaption: "Add Record",
  112. editCaption: "Edit Record",
  113. bSubmit: "Submit",
  114. bCancel: "Cancel",
  115. bClose: "Close",
  116. saveData: "Data has been changed! Save changes?",
  117. bYes: "Yes",
  118. bNo: "No",
  119. bExit: "Cancel",
  120. msg: {
  121. required: "Field is required",
  122. number: "Please, enter valid number",
  123. minValue: "value must be greater than or equal to ",
  124. maxValue: "value must be less than or equal to",
  125. email: "is not a valid e-mail",
  126. integer: "Please, enter valid integer value",
  127. date: "Please, enter valid date value",
  128. url: "is not a valid URL. Prefix required ('http://' or 'https://')",
  129. nodefined: " is not defined!",
  130. novalue: " return value is required!",
  131. customarray: "Custom function should return array!",
  132. customfcheck: "Custom function should be present in case of custom checking!"
  133. }
  134. },
  135. view: {
  136. caption: "View Record",
  137. bClose: "Close"
  138. },
  139. del: {
  140. caption: "Delete",
  141. msg: "Delete selected record(s)?",
  142. bSubmit: "Delete",
  143. bCancel: "Cancel"
  144. },
  145. nav: {
  146. edittext: "",
  147. edittitle: "Edit selected row",
  148. addtext: "",
  149. addtitle: "Add new row",
  150. deltext: "",
  151. deltitle: "Delete selected row",
  152. searchtext: "",
  153. searchtitle: "Find records",
  154. refreshtext: "",
  155. refreshtitle: "Reload Grid",
  156. alertcap: "Warning",
  157. alerttext: "Please, select row",
  158. viewtext: "",
  159. viewtitle: "View selected row",
  160. savetext: "",
  161. savetitle: "Save row",
  162. canceltext: "",
  163. canceltitle: "Cancel row editing"
  164. },
  165. col: {
  166. caption: "Select columns",
  167. bSubmit: "Ok",
  168. bCancel: "Cancel"
  169. },
  170. errors: {
  171. errcap: "Error",
  172. nourl: "No url is set",
  173. norecords: "No records to process",
  174. model: "Length of colNames <> colModel!"
  175. },
  176. formatter: {
  177. integer: {
  178. thousandsSeparator: ",",
  179. defaultValue: "0"
  180. },
  181. number: {
  182. decimalSeparator: ".",
  183. thousandsSeparator: ",",
  184. decimalPlaces: 2,
  185. defaultValue: "0.00"
  186. },
  187. currency: {
  188. decimalSeparator: ".",
  189. thousandsSeparator: ",",
  190. decimalPlaces: 2,
  191. prefix: "",
  192. suffix: "",
  193. defaultValue: "0.00"
  194. },
  195. date: {
  196. dayNames: [
  197. "Sun", "Mon", "Tue", "Wed", "Thr", "Fri", "Sat",
  198. "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"
  199. ],
  200. monthNames: [
  201. "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
  202. "January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
  203. ],
  204. AmPm: ["am", "pm", "AM", "PM"],
  205. S: function (j) {
  206. var ending = ["st", "nd", "rd", "th"];
  207. return j < 11 || j > 13 ? ending[Math.min((j - 1) % 10, 3)] : "th";
  208. },
  209. srcformat: "Y-m-d",
  210. newformat: "n/j/Y",
  211. masks: {
  212. // see http://php.net/manual/en/function.date.php for PHP format used in jqGrid
  213. // and see http://docs.jquery.com/UI/Datepicker/formatDate
  214. // and https://github.com/jquery/globalize#dates for alternative formats used frequently
  215. // one can find on https://github.com/jquery/globalize/tree/master/lib/cultures many
  216. // information about date, time, numbers and currency formats used in different countries
  217. // one should just convert the information in PHP format
  218. // short date:
  219. // n - Numeric representation of a month, without leading zeros
  220. // j - Day of the month without leading zeros
  221. // Y - A full numeric representation of a year, 4 digits
  222. // example: 3/1/2012 which means 1 March 2012
  223. ShortDate: "n/j/Y", // in jQuery UI Datepicker: "M/d/yyyy"
  224. // long date:
  225. // l - A full textual representation of the day of the week
  226. // F - A full textual representation of a month
  227. // d - Day of the month, 2 digits with leading zeros
  228. // Y - A full numeric representation of a year, 4 digits
  229. LongDate: "l, F d, Y", // in jQuery UI Datepicker: "dddd, MMMM dd, yyyy"
  230. // long date with long time:
  231. // l - A full textual representation of the day of the week
  232. // F - A full textual representation of a month
  233. // d - Day of the month, 2 digits with leading zeros
  234. // Y - A full numeric representation of a year, 4 digits
  235. // g - 12-hour format of an hour without leading zeros
  236. // i - Minutes with leading zeros
  237. // s - Seconds, with leading zeros
  238. // A - Uppercase Ante meridiem and Post meridiem (AM or PM)
  239. FullDateTime: "l, F d, Y g:i:s A", // in jQuery UI Datepicker: "dddd, MMMM dd, yyyy h:mm:ss tt"
  240. // month day:
  241. // F - A full textual representation of a month
  242. // d - Day of the month, 2 digits with leading zeros
  243. MonthDay: "F d", // in jQuery UI Datepicker: "MMMM dd"
  244. // short time (without seconds)
  245. // g - 12-hour format of an hour without leading zeros
  246. // i - Minutes with leading zeros
  247. // A - Uppercase Ante meridiem and Post meridiem (AM or PM)
  248. ShortTime: "g:i A", // in jQuery UI Datepicker: "h:mm tt"
  249. // long time (with seconds)
  250. // g - 12-hour format of an hour without leading zeros
  251. // i - Minutes with leading zeros
  252. // s - Seconds, with leading zeros
  253. // A - Uppercase Ante meridiem and Post meridiem (AM or PM)
  254. LongTime: "g:i:s A", // in jQuery UI Datepicker: "h:mm:ss tt"
  255. // month with year
  256. // Y - A full numeric representation of a year, 4 digits
  257. // F - A full textual representation of a month
  258. YearMonth: "F, Y" // in jQuery UI Datepicker: "MMMM, yyyy"
  259. }
  260. }
  261. }
  262. };
  263. $.jgrid = $.jgrid || {};
  264. var jgrid = $.jgrid;
  265. jgrid.locales = jgrid.locales || {};
  266. var locales = jgrid.locales;
  267. /**
  268. * Enum with different components of jqGrid.
  269. * @enum {number} @const
  270. */
  271. /*var INPUT_NAME_TYPE = {
  272. COL_NAME: 0,
  273. ADDITIONAL_PROPERTY: 1,
  274. ROWID: 2
  275. };*/
  276. /**
  277. * Enum with different components of jqGrid.
  278. * @enum {number} @const
  279. */
  280. var COMPONENT_NAMES = {
  281. // let us this - <table> from which grid is created. Then
  282. // gBox (grid box) - outer div which includes all grid components: $(this).closest(".ui-jqgrid")[0]
  283. // In the same way
  284. GRID_BOX_DIV: 0, // tagName: "div". class: "ui-jqgrid". Id: "gbox_" + gridId
  285. GRID_OVERLAY_DIV: 1, // tagName: "div". class: "jqgrid-overlay". Id: "lui_" + gridId
  286. LOADING_DIV: 2, // tagName: "div". class: "loading". Id: "load_" + gridId
  287. DIALOG_ALERT_DIV: 3, // tagName: "div". class: "ui-jqdialog". Id: "alertmod_" + gridId
  288. DIALOG_SEARCH_DIV: 4, // tagName: "div". class: "ui-jqdialog". Id: "searchmodfbox_" + gridId
  289. DIALOG_VIEW_DIV: 5, // tagName: "div". class: "ui-jqdialog". Id: "viewmod" + gridId
  290. DIALOG_EDIT_DIV: 6, // tagName: "div". class: "ui-jqdialog". Id: "editmod" + gridId
  291. DIALOG_DELETE_DIV: 7, // tagName: "div". class: "ui-jqdialog". Id: "delmod" + gridId
  292. GRID_VIEW_DIV: 8, // tagName: "div". class: "ui-jqgrid-view". Id: "gview_" + gridId
  293. TITLE_BAR_DIV: 9, // tagName: "div". class: "ui-jqgrid-titlebar" and either "ui-jqgrid-caption" or "ui-jqgrid-caption-rtl"
  294. UPPER_TOOLBAR_DIV: 10, // tagName: "div". class: "ui-userdata". Id: "tb_" + gridId
  295. TOP_PAGER_DIV: 11, // tagName: "div". class: "ui-jqgrid-toppager". Id: gridId + "_toppager"
  296. HEADER_DIV: 12, // tagName: "div". class: "ui-jqgrid-hdiv"
  297. HEADER_BOX_DIV: 13, // tagName: "div". class: either "ui-jqgrid-hdiv" or "ui-jqgrid-hbox-rtl"
  298. HEADER_TABLE: 14, // tagName: "table". class: "ui-jqgrid-htable"
  299. HEADER_COLS_ROW: 15, // tagName: "tr". class: "jqgfirstrow" or the row with column headers
  300. HEADER_COLS: 16, // tagName: "th". class: either "ui-first-th-rtl" or "ui-first-th-rtl"
  301. HEADER_ROWS: 47, // tagName: "tr". class: "ui-jqgrid-labels"
  302. HEADER_TH: 48, // tagName: "th". class: "ui-th-column" and either "ui-th-ltr" or "ui-th-rtl"
  303. HEADER_SORTABLE_DIV: 49, // tagName: "div". class: "ui-jqgrid-labels"
  304. HEADER_RESIZABLE_SPAN: 50, // tagName: "span". class: "ui-jqgrid-resize" and either "ui-jqgrid-resize-ltr" or "ui-jqgrid-resize-rtl"
  305. HEADER_SELECT_ALL_ROWS_CHECKBOX: 45, // tagName: "input" (can be changed to "button" in the future). class: "cbox". Id: "cb_" + gridId
  306. SEARCH_TOOLBAR: 17, // tagName: "tr". class: "ui-search-toolbar". Its direct children are th having class "ui-th-column" and optionally "ui-th-rtl"
  307. BODY_DIV: 18, // tagName: "div". class: "ui-jqgrid-bdiv"
  308. BODY_SCROLL_FULL_DIV: 19, // tagName: "div" - It can have height CSS property which simulate the total size of virtual data.
  309. BODY_SCROLL_TOP_DIV: 20, // tagName: "div" - It can have height CSS property which simulate virtual data before the current displayed in btable.
  310. BODY_TABLE: 21, // tagName: "table". class: "ui-jqgrid-btable". Id: gridId
  311. GRID: 21, // tagName: "table". class: "ui-jqgrid-btable". Id: gridId
  312. BODY_COLS_ROW: 22, // tagName: "tr". class: "jqgfirstrow"
  313. BODY_COLS: 23, // tagName: "td"
  314. BODY_DATA_ROWS: 24, // tagName: "tr". class: "jqgrow" and optionally "ui-row-rtl"
  315. FOOTER_DIV: 25, // tagName: "div". class: "ui-jqgrid-sdiv"
  316. FOOTER_BOX_DIV: 26, // tagName: "div". class: either "ui-jqgrid-hdiv" or "ui-jqgrid-hbox-rtl". ??? is it really needed ???
  317. FOOTER_TABLE: 27, // tagName: "table". class: "ui-jqgrid-ftable"
  318. FOOTER_DATA_ROWS: 28, // tagName: "tr". class: "footrow", optionally additionally "footrow-rtl"
  319. BOTTOM_TOOLBAR_DIV: 29, // tagName: "div". class: "ui-userdata". Id: "tb_" + gridId
  320. FROZEN_HEADER_DIV: 30, // tagName: "div". class: "frozen-div" and "ui-jqgrid-hdiv"
  321. // no hBox currently exists
  322. FROZEN_HEADER_TABLE: 31, // tagName: "table". class: "ui-jqgrid-htable"
  323. FROZEN_HEADER_COLS_ROW: 32, // tagName: "tr". class: "jqgfirstrow"
  324. FROZEN_HEADER_COLS: 33, // tagName: "th". class: either "ui-first-th-rtl" or "ui-first-th-rtl"
  325. FROZEN_SEARCH_TOOLBAR: 34, // tagName: "tr". class: "ui-search-toolbar". Its direct children are th having class "ui-th-column" and optionally "ui-th-rtl"
  326. // TODO: fix id of children of .ui-search-input to have no id duplicates with the main grid
  327. FROZEN_FOOTER_DIV: 35, // tagName: "div". class: "frozen-div" and "ui-jqgrid-sdiv"
  328. FROZEN_FOOTER_TABLE: 36, // tagName: "table". class: "ui-jqgrid-ftable"
  329. FROZEN_FOOTER_DATA_ROWS: 37, // tagName: "tr". class: "footrow", optionally additionally "footrow-rtl"
  330. FROZEN_BODY_DIV: 38, // tagName: "div". class: "frozen-div" and "ui-jqgrid-bdiv"
  331. // no full scroll div and top scroll div is currently exist
  332. FROZEN_BODY_TABLE: 39, // tagName: "table". class: "ui-jqgrid-btable". Id: gridId + "_frozen"
  333. FROZEN_BODY_COLS_ROW: 40, // tagName: "tr". class: "jqgfirstrow"
  334. FROZEN_BODY_COLS: 41, // tagName: "td"
  335. FROZEN_BODY_DATA_ROWS: 42, // tagName: "tr". class: "jqgrow" and optionally "ui-row-rtl"
  336. // TODO: fix id of children of .jqgrow to have no id duplicates with the main grid
  337. COLUMN_RESIZER_DIV: 43, // tagName: "div". class: "ui-jqgrid-resize-mark". Id: "rs_m" + gridId
  338. BOTTOM_PAGER_DIV: 44, // tagName: "div". class: "ui-jqgrid-pager"
  339. SEARCH_OPERATION_MENU_UL: 46 // tagName: "ul". class: "ui-search-menu". id="sopt_menu"
  340. };
  341. if (jgrid.defaults == null || $.isEmptyObject(locales) || locales["en-US"] === undefined) {
  342. // set English options only if no grid.locale-XX.js file are included before jquery.jqGrid.min.js or jquery.jqGrid.src.js
  343. // the files included AFTER jquery.jqGrid.min.js or jquery.jqGrid.src.js will just overwrite all the settings which were set previously
  344. // We can set locInfo under $.jgrid additionally to setting under $.jgrid.locales[locale]
  345. // only to have more compatibility with the previous version of jqGrid.
  346. // We don't make this currently.
  347. if (locales["en-US"] === undefined) {
  348. $.extend(true, jgrid, /*englishLanguageDefaults,*/ {
  349. locales: {
  350. "en-US": englishLanguageDefaults // and for English US
  351. }
  352. });
  353. }
  354. jgrid.defaults = jgrid.defaults || {};
  355. if (jgrid.defaults.locale === undefined) {
  356. jgrid.defaults.locale = "en-US";
  357. }
  358. }
  359. jgrid.defaults = jgrid.defaults || {};
  360. var defaults = jgrid.defaults;
  361. //if (jgrid.defaults.locale && locales[jgrid.defaults.locale]) {
  362. // $.extend(true, $.jgrid, locales[jgrid.defaults.locale]); // add to improve compatibility only
  363. //}
  364. $.extend(true, jgrid, {
  365. /** @const */
  366. version: "4.15.6-pre",
  367. /** @const */
  368. productName: "free jqGrid",
  369. defaults: {},
  370. search: {},
  371. edit: {},
  372. view: {},
  373. del: {},
  374. nav: {},
  375. col: {},
  376. errors: {},
  377. formatter: {
  378. unused: "" // used only to detect whether the changes are overwritten because of wrong usage
  379. },
  380. icons: {
  381. jQueryUI: {
  382. common: "ui-icon",
  383. pager: {
  384. first: "ui-icon-seek-first",
  385. prev: "ui-icon-seek-prev",
  386. next: "ui-icon-seek-next",
  387. last: "ui-icon-seek-end"
  388. },
  389. sort: {
  390. asc: "ui-icon-triangle-1-n",
  391. desc: "ui-icon-triangle-1-s"
  392. },
  393. gridMinimize: {
  394. visible: "ui-icon-circle-triangle-n",
  395. hidden: "ui-icon-circle-triangle-s"
  396. },
  397. nav: {
  398. edit: "ui-icon-pencil",
  399. add: "ui-icon-plus",
  400. del: "ui-icon-trash",
  401. search: "ui-icon-search",
  402. refresh: "ui-icon-refresh",
  403. view: "ui-icon-document",
  404. save: "ui-icon-disk",
  405. cancel: "ui-icon-cancel",
  406. newbutton: "ui-icon-newwin"
  407. },
  408. actions: {
  409. edit: "ui-icon-pencil",
  410. del: "ui-icon-trash",
  411. save: "ui-icon-disk",
  412. cancel: "ui-icon-cancel"
  413. },
  414. form: {
  415. close: "ui-icon-closethick",
  416. prev: "ui-icon-triangle-1-w",
  417. next: "ui-icon-triangle-1-e",
  418. save: "ui-icon-disk",
  419. undo: "ui-icon-close",
  420. del: "ui-icon-scissors",
  421. cancel: "ui-icon-cancel",
  422. resizableLtr: "ui-resizable-se ui-icon ui-icon-gripsmall-diagonal-se"
  423. },
  424. search: {
  425. search: "ui-icon-search",
  426. reset: "ui-icon-arrowreturnthick-1-w",
  427. query: "ui-icon-comment"
  428. },
  429. subgrid: {
  430. plus: "ui-icon-plus",
  431. minus: "ui-icon-minus",
  432. openLtr: "ui-icon-caret-1-sw",
  433. openRtl: "ui-icon-caret-1-se"
  434. },
  435. grouping: {
  436. plus: "ui-icon-circlesmall-plus",
  437. minus: "ui-icon-circlesmall-minus"
  438. },
  439. treeGrid: {
  440. minus: "ui-icon-triangle-1-s",
  441. leaf: "ui-icon-radio-off",
  442. plusLtr: "ui-icon-triangle-1-e",
  443. plusRtl: "ui-icon-triangle-1-w"
  444. }
  445. },
  446. fontAwesome: {
  447. common: "fa",
  448. pager: {
  449. common: "fa-fw",
  450. first: "fa-step-backward",
  451. prev: "fa-backward",
  452. next: "fa-forward",
  453. last: "fa-step-forward"
  454. },
  455. sort: {
  456. common: "fa-lg", // common: "",
  457. asc: "fa-sort-asc", // asc: "fa-sort-amount-asc",
  458. desc: "fa-sort-desc" // desc: "fa-sort-amount-desc"
  459. },
  460. gridMinimize: {
  461. visible: "fa-chevron-circle-up",
  462. hidden: "fa-chevron-circle-down"
  463. },
  464. nav: {
  465. common: "fa-lg fa-fw",
  466. edit: "fa-pencil",
  467. add: "fa-plus",
  468. del: "fa-trash-o",
  469. search: "fa-search",
  470. refresh: "fa-refresh",
  471. view: "fa-file-o",
  472. save: "fa-floppy-o",
  473. cancel: "fa-ban",
  474. newbutton: "fa-external-link"
  475. },
  476. actions: {
  477. common: "fa-fw",
  478. edit: "fa-pencil",
  479. del: "fa-trash-o",
  480. save: "fa-floppy-o",
  481. cancel: "fa-ban"
  482. },
  483. form: {
  484. close: "fa-times",
  485. prev: "fa-caret-left",
  486. next: "fa-caret-right",
  487. save: "fa-floppy-o",
  488. undo: "fa-undo",
  489. del: "fa-trash-o",
  490. cancel: "fa-ban",
  491. resizableLtr: "fa-rss fa-rotate-270"
  492. },
  493. search: {
  494. search: "fa-search",
  495. reset: "fa-undo",
  496. query: "fa-comments-o"
  497. },
  498. subgrid: {
  499. common: "fa-fw",
  500. plus: "fa-plus",
  501. minus: "fa-minus",
  502. openLtr: "fa-reply fa-rotate-180",
  503. openRtl: "fa-share fa-rotate-180"
  504. },
  505. grouping: {
  506. common: "fa-fw",
  507. plus: "fa-plus-square-o",
  508. minus: "fa-minus-square-o"
  509. },
  510. treeGrid: {
  511. common: "fa-fw",
  512. minus: "fa-lg fa-sort-desc",
  513. leaf: "fa-dot-circle-o",
  514. plusLtr: "fa-lg fa-caret-right",
  515. plusRtl: "fa-lg fa-caret-left"
  516. },
  517. checkbox: {
  518. checkedClasses: "fa-check-square-o",
  519. checked: "fa-check-square-o fa-lg",
  520. unchecked: "fa-square-o fa-lg"
  521. }
  522. },
  523. fontAwesome5: {
  524. //common: "fas", //"fa"
  525. pager: {
  526. common: "fa-fw",
  527. first: "fa-step-backward",
  528. prev: "fa-backward",
  529. next: "fa-forward",
  530. last: "fa-step-forward"
  531. },
  532. sort: {
  533. common: "fa-lg", // common: "",
  534. asc: "fa-sort-up", //"fa-sort-asc", // asc: "fa-sort-amount-asc",
  535. desc: "fa-sort-down" //"fa-sort-desc" // desc: "fa-sort-amount-desc"
  536. },
  537. gridMinimize: {
  538. visible: "fa-chevron-circle-up",
  539. hidden: "fa-chevron-circle-down"
  540. },
  541. nav: {
  542. common: "fa-lg fa-fw",
  543. edit: "fa-pencil-alt",
  544. add: "fa-plus",
  545. del: "fa-trash-alt",
  546. search: "fa-search",
  547. refresh: "fa-sync", //"fa-refresh",
  548. view: "fa-file",
  549. save: "fa-save",
  550. cancel: "fa-ban",
  551. newbutton: "fa-external-link-alt"
  552. },
  553. actions: {
  554. common: "fa-fw",
  555. edit: "fa-pencil-alt",
  556. del: "fa-trash-alt",
  557. save: "fa-save",
  558. cancel: "fa-ban"
  559. },
  560. form: {
  561. close: "fa-times",
  562. prev: "fa-caret-left",
  563. next: "fa-caret-right",
  564. save: "fa-save",
  565. undo: "fa-undo",
  566. del: "fa-trash-alt",
  567. cancel: "fa-ban",
  568. resizableLtr: "fa-rss fa-lg fa-rotate-270"
  569. },
  570. search: {
  571. search: "fa-search",
  572. reset: "fa-undo",
  573. query: "fa-comments"
  574. },
  575. subgrid: {
  576. common: "fa-fw",
  577. plus: "fa-plus",
  578. minus: "fa-minus",
  579. openLtr: "fa-reply fa-rotate-180",
  580. openRtl: "fa-share fa-rotate-180"
  581. },
  582. grouping: {
  583. common: "fa-fw",
  584. plus: "fa-plus-square",
  585. minus: "fa-minus-square"
  586. },
  587. treeGrid: {
  588. common: "fa-fw",
  589. minus: "fa-lg fa-sort-down", //"fa-lg fa-sort-desc",
  590. leaf: "fa-dot-circle",
  591. plusLtr: "fa-lg fa-caret-right",
  592. plusRtl: "fa-lg fa-caret-left"
  593. },
  594. checkbox: {
  595. ignoreParents: true,
  596. checkedClasses: "fa-check-square",
  597. checked: "far fa-check-square fa-lg",
  598. unchecked: "far fa-square fa-lg"
  599. }
  600. },
  601. fontAwesomeBrands: {
  602. baseIconSet: "fontAwesome5",
  603. common: "fab"
  604. },
  605. fontAwesomeLight: {
  606. baseIconSet: "fontAwesome5",
  607. common: "fal"
  608. },
  609. fontAwesomeRegular: {
  610. baseIconSet: "fontAwesome5",
  611. common: "far"
  612. },
  613. fontAwesomeSolid: {
  614. baseIconSet: "fontAwesome5",
  615. common: "fas"
  616. },
  617. fontAwesomeSVG: {
  618. baseIconSet: "fontAwesome5",
  619. common: "fas"
  620. },
  621. glyph: {
  622. common: "glyphicon",
  623. pager: {
  624. common: "",
  625. first: "glyphicon-step-backward",
  626. prev: "glyphicon-backward",
  627. next: "glyphicon-forward",
  628. last: "glyphicon-step-forward"
  629. },
  630. sort: {
  631. common: "",
  632. asc: "glyphicon-triangle-top",
  633. desc: "glyphicon-triangle-bottom"
  634. },
  635. gridMinimize: {
  636. visible: "glyphicon-circle-arrow-up",
  637. hidden: "glyphicon-circle-arrow-down"
  638. },
  639. nav: {
  640. common: "",
  641. edit: "glyphicon-edit",
  642. add: "glyphicon-plus",
  643. del: "glyphicon-trash",
  644. search: "glyphicon-search",
  645. refresh: "glyphicon-refresh",
  646. view: "glyphicon-file", // glyphicon glyphicon-th-list
  647. save: "glyphicon-save",
  648. cancel: "glyphicon-ban-circle",
  649. newbutton: "glyphicon-new-window"
  650. },
  651. actions: {
  652. common: "",
  653. edit: "glyphicon-edit",
  654. del: "glyphicon-trash",
  655. save: "glyphicon-save",
  656. cancel: "glyphicon-ban-circle"
  657. },
  658. form: {
  659. close: "glyphicon-remove-circle",
  660. prev: "glyphicon-step-backward",
  661. next: "glyphicon-step-forward",
  662. save: "glyphicon-save",
  663. undo: "glyphicon-repeat",
  664. del: "glyphicon-trash",
  665. cancel: "glyphicon-ban-circle",
  666. resizableLtr: "glyphicon-import"
  667. },
  668. search: {
  669. search: "glyphicon-search",
  670. reset: "glyphicon-repeat",
  671. query: "glyphicon-cog" //"glyphicon-comment"
  672. },
  673. subgrid: {
  674. common: "",
  675. plus: "glyphicon-zoom-in", //"glyphicon-plus", "glyphicon-th-list",
  676. minus: "glyphicon-zoom-out", // "glyphicon-minus",
  677. openLtr: "glyphicon-indent-left",
  678. openRtl: "glyphicon-indent-left"
  679. },
  680. grouping: {
  681. common: "",
  682. plus: "glyphicon-expand",
  683. minus: "glyphicon-collapse-down"
  684. },
  685. treeGrid: {
  686. common: "",
  687. minus: "glyphicon-triangle-bottom",
  688. leaf: "glyphicon-record", // glyphicon-unchecked
  689. plusLtr: "glyphicon-triangle-right",
  690. plusRtl: "glyphicon-triangle-left"
  691. },
  692. checkbox: {
  693. checkedClasses: "glyphicon-check",
  694. checked: "glyphicon-check",
  695. unchecked: "glyphicon-unchecked"
  696. }
  697. }
  698. },
  699. guiStyles: {
  700. jQueryUI: {
  701. gBox: "ui-jqgrid-jquery-ui ui-widget ui-widget-content ui-corner-all", // ui-widget-content??? for the children of gbox
  702. gView: "",
  703. overlay: "ui-widget-overlay",
  704. loading: "ui-state-default ui-state-active",
  705. hDiv: "ui-state-default ui-corner-top",
  706. hTable: "",
  707. colHeaders: "ui-state-default",
  708. states: {
  709. select: "ui-state-highlight",
  710. disabled: "ui-state-disabled ui-jqgrid-disablePointerEvents",
  711. hover: "ui-state-hover", // can be table-hover on <table> only and style like .table-hover tbody tr:hover td
  712. error: "ui-state-error",
  713. active: "ui-state-active",
  714. textOfClickable: "ui-state-default"
  715. },
  716. dialog: {
  717. header: "ui-widget-header ui-dialog-titlebar ui-corner-all ui-helper-clearfix",
  718. window: "ui-jqgrid-jquery-ui ui-widget ui-widget-content ui-corner-all ui-front",
  719. document: "",
  720. subdocument: "",
  721. body: "",
  722. footer: "",
  723. content: "ui-widget-content",
  724. hr: "ui-widget-content",
  725. closeButton: "ui-corner-all",
  726. fmButton: "ui-state-default",
  727. dataField: "ui-widget-content ui-corner-all",
  728. viewCellLabel: "ui-widget-content",
  729. viewLabel: "",
  730. viewCellData: "ui-widget-content",
  731. viewData: "",
  732. leftCorner: "ui-corner-left",
  733. rightCorner: "ui-corner-right",
  734. defaultCorner: "ui-corner-all"
  735. },
  736. filterToolbar: {
  737. dataField: "ui-widget-content"
  738. },
  739. subgrid: {
  740. thSubgrid: "ui-state-default", // used only with subGridModel
  741. rowSubTable: "ui-widget-content", // used only with subGridModel additionally to ui-subtblcell
  742. row: "ui-widget-content", // class of the subgrid row, additional to ui-subgrid
  743. tdStart: "", // it can be with span over rownumber and multiselect columns
  744. tdWithIcon: "ui-widget-content", // class of cell with +- icon, additional to subgrid-cell
  745. buttonDiv: "",
  746. button: "",
  747. tdData: "ui-widget-content", // class of main td with span over the grid, additional subgrid-data
  748. legacyTable: ""
  749. },
  750. grid: "",
  751. gridRow: "ui-widget-content",
  752. rowNum: "ui-state-default",
  753. gridFooter: "",
  754. rowFooter: "ui-widget-content",
  755. gridTitle: "ui-widget-header ui-corner-top",
  756. gridError: "ui-state-error",
  757. gridErrorText: "",
  758. titleButton: "ui-corner-all",
  759. toolbarUpper: "ui-state-default",
  760. toolbarBottom: "ui-state-default",
  761. actionsDiv: "ui-widget-content",
  762. actionsButton: "ui-corner-all",
  763. pager: {
  764. pager: "ui-state-default",
  765. pagerButton: "ui-corner-all",
  766. pagerInput: "ui-widget-content",
  767. pagerSelect: "ui-widget-content"
  768. },
  769. navButton: "ui-corner-all",
  770. searchDialog: {
  771. operator: "ui-corner-all",
  772. label: "ui-corner-all",
  773. elem: "ui-corner-all",
  774. operationGroup: "",
  775. addRuleButton: "ui-corner-all",
  776. deleteRuleButton: "ui-corner-all",
  777. operationSelect: "ui-corner-all",
  778. addGroupButton: "ui-corner-all",
  779. deleteGroupButton: "ui-corner-all"
  780. },
  781. searchToolbar: {
  782. menu: "ui-menu-jqueryui ui-menu ui-widget ui-widget-content ui-corner-all",
  783. menuItem: "ui-menu-item",
  784. menuItemButton: "ui-corner-all",
  785. operButton: "ui-corner-all",
  786. clearButton: "ui-corner-all"
  787. },
  788. top: "ui-corner-top",
  789. bottom: "ui-corner-bottom",
  790. resizer: "ui-widget-header"
  791. },
  792. bootstrap: {
  793. gBox: "ui-jqgrid-bootstrap",
  794. gView: "panel-info",
  795. overlay: "modal-backdrop",
  796. loading: "alert alert-info",
  797. hDiv: "",
  798. hTable: "table table-hover table-condensed table-bordered",
  799. colHeaders: "",
  800. states: {
  801. select: "success",
  802. disabled: "disabled ui-jqgrid-disablePointerEvents",
  803. hover: "active",
  804. error: "danger",
  805. active: "active",
  806. textOfClickable: ""
  807. },
  808. dialog: {
  809. header: "modal-header",
  810. window: "modal ui-jqgrid-bootstrap",
  811. document: "modal-dialog",
  812. subdocument: "modal-content",
  813. body: "modal-body",
  814. footer: "modal-footer",
  815. content: "modal-content",
  816. hr: "hidden",
  817. closeButton: "btn btn-xs btn-default",
  818. fmButton: "btn btn-default",
  819. dataField: "form-control",
  820. viewCellLabel: "",
  821. viewLabel: "control-label",
  822. viewCellData: "",
  823. viewData: "form-control",
  824. leftCorner: "",
  825. rightCorner: "",
  826. defaultCorner: ""
  827. },
  828. filterToolbar: {
  829. dataField: "form-control"
  830. },
  831. subgrid: {
  832. thSubgrid: "",
  833. rowSubTable: "",
  834. row: "",
  835. tdStart: "",
  836. tdWithIcon: "",
  837. buttonDiv: "",
  838. button: "btn btn-xs",
  839. tdData: "",
  840. legacyTable: "table table-condensed table-hover table-bordered"
  841. },
  842. grid: "table table-condensed table-hover table-bordered",
  843. gridRow: "",
  844. rowNum: "",
  845. gridFooter: "table table-hover table-condensed table-bordered",
  846. rowFooter: "",
  847. gridTitle: "",
  848. gridError: "alert alert-danger",
  849. gridErrorText: "sr-only",
  850. titleButton: "btn btn-xs btn-default",
  851. actionsDiv: "",
  852. actionsButton: "btn btn-xs btn-default",
  853. toolbarUpper: "",
  854. toolbarBottom: "",
  855. pager: {
  856. pager: "panel-footer",
  857. pagerButton: "btn btn-xs",
  858. pagerInput: "form-control",
  859. pagerSelect: "form-control"
  860. },
  861. navButton: "btn btn-xs",
  862. searchDialog: {
  863. operator: "form-control",
  864. label: "form-control",
  865. elem: "form-control",
  866. operationGroup: "form-inline",
  867. addRuleButton: "btn btn-xs btn-default",
  868. deleteRuleButton: "btn btn-xs btn-default",
  869. operationSelect: "form-control",
  870. addGroupButton: "btn btn-xs btn-default",
  871. deleteGroupButton: "btn btn-xs btn-default"
  872. },
  873. searchToolbar: {
  874. menu: "dropdown-menu",
  875. menuItem: "",
  876. menuItemButton: "ui-corner-all",
  877. operButton: "btn btn-xs btn-default",
  878. clearButton: "btn btn-xs btn-default"
  879. },
  880. top: "ui-jqgrid-bootstrap-corner-top",
  881. bottom: "ui-jqgrid-bootstrap-corner-bottom",
  882. resizer: "ui-jqgrid-bootstrap"
  883. },
  884. bootstrapPrimary: {
  885. baseGuiStyle: "bootstrap",
  886. dialog: {
  887. closeButton: "btn btn-xs close",
  888. fmButton: "btn btn-primary"
  889. },
  890. searchDialog: {
  891. addRuleButton: "btn btn-xs btn-primary",
  892. deleteRuleButton: "btn btn-xs btn-primary",
  893. addGroupButton: "btn btn-xs btn-primary",
  894. deleteGroupButton: "btn btn-xs btn-primary"
  895. }
  896. },
  897. bootstrap4: {
  898. gBox: "ui-jqgrid-bootstrap",
  899. gView: "card",
  900. overlay: "modal-backdrop",
  901. loading: "alert alert-info",
  902. hDiv: "",
  903. hTable: "table table-hover table-sm table-bordered",
  904. colHeaders: "",
  905. states: {
  906. select: "table-success",
  907. disabled: "disabled ui-jqgrid-disablePointerEvents",
  908. hover: "active",
  909. hoverTh: "table-active",
  910. error: "danger",
  911. active: "active",
  912. textOfClickable: ""
  913. },
  914. dialog: {
  915. header: "modal-header",
  916. window: "modal ui-jqgrid-bootstrap",
  917. document: "modal-dialog",
  918. subdocument: "modal-content",
  919. body: "modal-body",
  920. footer: "modal-footer",
  921. content: "modal-content",
  922. hr: "d-none",
  923. closeButton: "btn btn-xs btn-outline-primary",
  924. fmButton: "btn btn-outline-secondary",
  925. dataField: "form-control",
  926. viewCellLabel: "",
  927. viewLabel: "control-label",
  928. viewCellData: "",
  929. viewData: "form-control",
  930. leftCorner: "",
  931. rightCorner: "",
  932. defaultCorner: ""
  933. },
  934. filterToolbar: {
  935. dataField: "form-control"
  936. },
  937. subgrid: {
  938. thSubgrid: "",
  939. rowSubTable: "",
  940. row: "",
  941. tdStart: "",
  942. tdWithIcon: "",
  943. buttonDiv: "",
  944. button: "btn btn-xs",
  945. tdData: "",
  946. legacyTable: "table table-condensed table-hover table-bordered"
  947. },
  948. grid: "table table-condensed table-hover table-bordered",
  949. gridRow: "",
  950. rowNum: "",
  951. gridFooter: "table table-hover table-condensed table-bordered",
  952. rowFooter: "",
  953. gridTitle: "",
  954. gridError: "alert alert-danger",
  955. gridErrorText: "sr-only",
  956. titleButton: "btn btn-xs btn-outline-primary",
  957. actionsDiv: "",
  958. actionsButton: "btn btn-xs btn-outline-secondary",
  959. toolbarUpper: "",
  960. toolbarBottom: "",
  961. pager: {
  962. pager: "card-footer",
  963. pagerButton: "btn btn-xs",
  964. pagerInput: "form-control",
  965. pagerSelect: "form-control"
  966. },
  967. navButton: "btn btn-xs",
  968. searchDialog: {
  969. operator: "form-control",
  970. label: "form-control",
  971. elem: "form-control",
  972. operationGroup: "form-inline",
  973. addRuleButton: "btn btn-xs btn-default",
  974. deleteRuleButton: "btn btn-xs btn-default",
  975. operationSelect: "form-control",
  976. addGroupButton: "btn btn-xs btn-default",
  977. deleteGroupButton: "btn btn-xs btn-default"
  978. },
  979. searchToolbar: {
  980. menu: "dropdown-menu",
  981. menuItem: "",
  982. menuItemButton: "dropdown-item",
  983. operButton: "btn btn-xs btn-outline-secondary",
  984. clearButton: "btn btn-xs btn-outline-secondary"
  985. },
  986. top: "ui-jqgrid-bootstrap-corner-top",
  987. bottom: "ui-jqgrid-bootstrap-corner-bottom",
  988. resizer: "ui-jqgrid-bootstrap"
  989. }
  990. },
  991. htmlDecode: function (value) {
  992. if (value && (value === "&nbsp;" ||
  993. value === "&#160;" ||
  994. (value.length === 1 && value.charCodeAt(0) === 160))) {
  995. return "";
  996. }
  997. return !value ?
  998. value :
  999. String(value)
  1000. .replace(/&gt;/g, ">")
  1001. .replace(/&lt;/g, "<")
  1002. .replace(/&#x27;/g, "'")
  1003. .replace(/&#x2F;/g, "\/")
  1004. .replace(/&#39;/g, "'")
  1005. .replace(/&#47;/g, "\/")
  1006. .replace(/&quot;/g, "\"")
  1007. .replace(/&amp;/g, "&");
  1008. },
  1009. htmlEncode: function (value) {
  1010. // see https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content
  1011. return !value ?
  1012. value :
  1013. String(value)
  1014. .replace(/&/g, "&amp;")
  1015. .replace(/"/g, "&quot;")
  1016. .replace(/'/g, "&#39;")
  1017. .replace(/\//g, "&#47;")
  1018. .replace(/</g, "&lt;")
  1019. .replace(/>/g, "&gt;");
  1020. },
  1021. oldEncodePostedData: function (value) {
  1022. return !value ?
  1023. value :
  1024. String(value)
  1025. .replace(/&/g, "&amp;")
  1026. .replace(/"/g, "&quot;")
  1027. .replace(/</g, "&lt;")
  1028. .replace(/>/g, "&gt;");
  1029. },
  1030. oldDecodePostedData: function (value) {
  1031. if (value && (value === "&nbsp;" ||
  1032. value === "&#160;" ||
  1033. (value.length === 1 && value.charCodeAt(0) === 160))) {
  1034. return "";
  1035. }
  1036. return !value ?
  1037. value :
  1038. String(value)
  1039. .replace(/&gt;/g, ">")
  1040. .replace(/&lt;/g, "<")
  1041. .replace(/&quot;/g, "\"")
  1042. .replace(/&amp;/g, "&");
  1043. },
  1044. clearArray: function (ar) {
  1045. // see http://jsperf.com/empty-javascript-array
  1046. while (ar.length > 0) {
  1047. ar.pop();
  1048. }
  1049. },
  1050. format: function (format) { //jqgformat
  1051. var args = $.makeArray(arguments).slice(1);
  1052. if (format == null) { format = ""; }
  1053. return format.replace(/\{(\d+)\}/g, function (m, i) {
  1054. return args[i];
  1055. });
  1056. },
  1057. template: function (format) { //jqgformat
  1058. var args = $.makeArray(arguments).slice(1), j, al = args.length;
  1059. if (format == null) {
  1060. format = "";
  1061. }
  1062. return format.replace(/\{([\w\-]+)(?:\:([\w\.]*)(?:\((\.*?)?\))?)?\}/g, function (m, i) {
  1063. var nmarr, k;
  1064. if (!isNaN(parseInt(i, 10))) {
  1065. return args[parseInt(i, 10)];
  1066. }
  1067. for (j = 0; j < al; j++) {
  1068. if ($.isArray(args[j])) {
  1069. nmarr = args[j];
  1070. k = nmarr.length;
  1071. while (k--) {
  1072. if (i === nmarr[k].nm) {
  1073. return nmarr[k].v;
  1074. }
  1075. }
  1076. }
  1077. }
  1078. });
  1079. },
  1080. msie: navigator.appName === "Microsoft Internet Explorer",
  1081. msiever: function () {
  1082. // Trident/4.0 - Internet Explorer 8,
  1083. // Trident/5.0 - Internet Explorer 9,
  1084. // Trident/6.0 - Internet Explorer 10
  1085. // Trident/7.0 - IE11
  1086. // Version tokens MSIE might not reflect the actual version of the browser
  1087. // If Compatibility View is enabled for a webpage or the browser mode is set to an earlier version
  1088. var rv = -1, match;
  1089. if (navigator.appName === "Microsoft Internet Explorer") {
  1090. match = /(MSIE) ([0-9]{1,}[.0-9]{0,})/.exec(navigator.userAgent);
  1091. if (match != null && match.length === 3) {
  1092. rv = parseFloat(match[2] || -1);
  1093. }
  1094. } else if (navigator.appName === "Netscape") {
  1095. match = /rv:([0-9]{1,}[.0-9]{0,})/.exec(navigator.userAgent);
  1096. if (match != null && match.length === 2) {
  1097. rv = parseFloat(match[1] || -1);
  1098. }
  1099. }
  1100. return rv;
  1101. },
  1102. fixMaxHeightOfDiv: function (height) {
  1103. // we place the fixing of maximal height in the method to allow easy
  1104. // to overwrite the method and to change the behaviour of jqGrid
  1105. // in case of usage virtual scrolling
  1106. if (navigator.appName === "Microsoft Internet Explorer") {
  1107. return Math.min(height, 1533917); // ??? 1022611
  1108. }
  1109. if (/(Firefox)/.exec(navigator.userAgent) != null) {
  1110. return Math.min(height, 17895696);
  1111. }
  1112. return height;
  1113. },
  1114. getRelativeRect: function (elem) {
  1115. var relativeTo = elem instanceof $ && elem.length > 0 ? elem[0] : elem,
  1116. relativeToOuterHeight = $(relativeTo).outerHeight(),
  1117. gbox = $(this).closest(".ui-jqgrid")[0],
  1118. rectRelativeTo, rectGbox;
  1119. if (!gbox) {
  1120. return { top: 0, left: 0 };
  1121. }
  1122. rectRelativeTo = relativeTo.getBoundingClientRect != null ?
  1123. relativeTo.getBoundingClientRect() :
  1124. $(relativeTo).offset();
  1125. rectGbox = gbox.getBoundingClientRect != null ?
  1126. gbox.getBoundingClientRect() :
  1127. $(gbox).offset();
  1128. return {
  1129. top: rectRelativeTo.top + relativeToOuterHeight - rectGbox.top,
  1130. //right: rectGbox.right - rectRelativeTo.right,
  1131. left: rectRelativeTo.left - rectGbox.left
  1132. };
  1133. },
  1134. getCellIndex: function (cell) {
  1135. var c = $(cell);
  1136. if (c.is("tr")) { return -1; }
  1137. c = (!c.is("td") && !c.is("th") ? c.closest("td,th") : c)[0];
  1138. if (c == null) { return -1; }
  1139. if (jgrid.msie) { return $.inArray(c, c.parentNode.cells); }
  1140. return c.cellIndex;
  1141. },
  1142. stripHtml: function (v) {
  1143. v = String(v);
  1144. if (v) {
  1145. v = v.replace(/<("[^"]*"|'[^']*'|[^'">])*>/gi, "");
  1146. return (v && v !== "&nbsp;" && v !== "&#160;") ? v.replace(/"/g, "'") : "";
  1147. }
  1148. return v;
  1149. },
  1150. stripPref: function (pref, id) {
  1151. var obj = $.type(pref);
  1152. if (obj === "string" || obj === "number") {
  1153. pref = String(pref);
  1154. id = pref !== "" ? String(id).replace(String(pref), "") : id;
  1155. }
  1156. return id;
  1157. },
  1158. getRes: function (basePath, path) {
  1159. var pathParts = path.split("."), n = pathParts.length, i;
  1160. if (basePath == null) {
  1161. return undefined;
  1162. }
  1163. for (i = 0; i < n; i++) {
  1164. if (!pathParts[i]) {
  1165. return null;
  1166. }
  1167. basePath = basePath[pathParts[i]];
  1168. if (basePath === undefined) {
  1169. break;
  1170. }
  1171. if (typeof basePath === "string") {
  1172. return basePath;
  1173. }
  1174. }
  1175. return basePath;
  1176. },
  1177. parseDate: function (format, date, newformat, opts) {
  1178. // It seems that the code was "imported" by Tony from http://blog.stevenlevithan.com/archives/date-time-format
  1179. // Thus I include the reference to original
  1180. // Date Format 1.2.3 (c) 2007-2009 Steven Levithan <stevenlevithan.com> MIT license
  1181. // The code can be found on https://github.com/felixge/node-dateformat/blob/master/lib/dateformat.js
  1182. // It would be probabbly good idea to support original date format additionally to the
  1183. // PHP data format used below.
  1184. var token = /\\.|[dDjlNSwzWFmMntLoYyaABgGhHisueIOPTZcrU]/g, dM, k, hl, timestamp = 0, offset = 0,
  1185. timezone = /\b(?:[PMCEA][SDP]T|(?:Pacific|Mountain|Central|Eastern|Atlantic) (?:Standard|Daylight|Prevailing) Time|(?:GMT|UTC)(?:[\-+]\d{4})?)\b/g,
  1186. timezoneClip = /[^\-+\dA-Z]/g,
  1187. msMatch = ((typeof date === "string") ? date.match(/^\/Date\((([\-+])?[0-9]+)(([\-+])([0-9]{2})([0-9]{2}))?\)\/$/) : null),
  1188. pad = function (value, length) {
  1189. value = String(value);
  1190. length = parseInt(length, 10) || 2;
  1191. while (value.length < length) { value = "0" + value; }
  1192. return value;
  1193. },
  1194. ts = { m: 1, d: 1, y: 1970, h: 0, i: 0, s: 0, u: 0 },
  1195. h12To24 = function (ampm, h) {
  1196. if (ampm === 0) {
  1197. if (h === 12) { h = 0; }
  1198. } else {
  1199. if (h !== 12) { h += 12; }
  1200. }
  1201. return h;
  1202. },
  1203. getDefOptions = function (p, options) {
  1204. // It could be multiple sources for date properties used below.
  1205. // Let us we need to use srcformat. The highest priority have
  1206. // opts.srcformat if it is specified. If the srcformat is not
  1207. // specified of if opts is undefined then one should use
  1208. // $.jgrid.locales.de.formatter.date.srcformat, for example,
  1209. // where "de" part is an example of the locale of the grid
  1210. // ($t.p.locale). There as the third important case existing
  1211. // because of compatibility only. The old place for formatter.date.srcformat
  1212. // was $.jgrid.formatter.date.srcformat (without "locales.de" part
  1213. // in the middle). Now such option should be not used, but
  1214. // because of some code where the old code of jqGrid was customized
  1215. // using $.jgrid.formatter instead of $.jgrid.locales[locale].formatter,
  1216. // one have to take in consideration the case. If such setting exist
  1217. // then one should use it (should use $.jgrid.formatter.date.srcformat)
  1218. // BEFORE the new default $.jgrid.locales.de.formatter.date.srcformat.
  1219. // As the result sue should search for all below properties in 3 sources:
  1220. // first in opts || {}, second in
  1221. // ($.jgrid.formatter || {}).date || {}
  1222. // and finally, if $t.p != null && $t.p.locale != null, under
  1223. // $.jgrid.locales[$t.p.locale].formatter.date
  1224. // oder (it's the same, just rewritten) under
  1225. // ((locales[$t.p.locale] || {}).formatter || {}).date
  1226. var props = ["AmPm", "dayNames", "masks", "monthNames", "userLocalTime", "parseRe", "S", "srcformat"],
  1227. root1 = options || {},
  1228. root2 = (jgrid.formatter || {}).date || {},
  1229. root3 = ((locales[(p || $.jgrid.defaults).locale] || {}).formatter || {}).date,
  1230. iProp, nProps = props.length, result = {}, prop;
  1231. for (iProp = 0; iProp < nProps; iProp++) {
  1232. prop = props[iProp];
  1233. if (root1[prop] !== undefined) { // root1.hasOwnProperty(prop)
  1234. result[prop] = root1[prop];
  1235. } else if (root2[prop] !== undefined) {// root2.hasOwnProperty(prop)
  1236. result[prop] = root2[prop];
  1237. } else if (root3[prop] !== undefined) {// root3.hasOwnProperty(prop)
  1238. result[prop] = root3[prop];
  1239. }
  1240. }
  1241. return result;
  1242. };
  1243. //opts = $.extend({}, (jgrid.formatter || {}).date,
  1244. // $t.p != null ?
  1245. // jgrid.getRes(locales[$t.p.locale], "formatter.date") || {} :
  1246. // {},
  1247. // opts || {});
  1248. opts = getDefOptions(this.p, opts);
  1249. // old lang files
  1250. if (opts.parseRe === undefined) {
  1251. opts.parseRe = /[#%\\\/:_;.,\t\s\-]/;
  1252. }
  1253. if (opts.masks.hasOwnProperty(format)) { format = opts.masks[format]; }
  1254. if (date && date != null) {
  1255. if (!isNaN(date) && String(format).toLowerCase() === "u") {
  1256. //Unix timestamp
  1257. timestamp = new Date(parseFloat(date) * 1000);
  1258. } else if (!isNaN(date) && String(format).toLowerCase() === "u1000") {
  1259. // Milliseconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
  1260. timestamp = new Date(parseFloat(date));
  1261. } else if (date.constructor === Date) {
  1262. timestamp = date;
  1263. // Microsoft date format support
  1264. } else if (msMatch !== null) {
  1265. timestamp = new Date(parseInt(msMatch[1], 10));
  1266. if (msMatch[3]) {
  1267. offset = Number(msMatch[5]) * 60 + Number(msMatch[6]);
  1268. offset *= ((msMatch[4] === "-") ? 1 : -1);
  1269. offset -= timestamp.getTimezoneOffset();
  1270. timestamp.setTime(Number(Number(timestamp) + (offset * 60 * 1000)));
  1271. }
  1272. } else {
  1273. //Support ISO8601Long that have Z at the end to indicate UTC timezone
  1274. if (opts.srcformat === "ISO8601Long" && date.charAt(date.length - 1) === "Z") {
  1275. offset -= (new Date()).getTimezoneOffset();
  1276. }
  1277. date = String(date).replace(/\T/g, "#").replace(/\t/, "%").split(opts.parseRe);
  1278. format = format.replace(/\T/g, "#").replace(/\t/, "%").split(opts.parseRe);
  1279. // parsing for month names and time
  1280. for (k = 0, hl = Math.min(format.length, date.length); k < hl; k++) {
  1281. switch (format[k]) {
  1282. case "M":
  1283. // A short textual representation of a month, three letters Jan through Dec
  1284. dM = $.inArray(date[k], opts.monthNames);
  1285. if (dM !== -1 && dM < 12) {
  1286. date[k] = dM + 1;
  1287. ts.m = date[k];
  1288. }
  1289. break;
  1290. case "F":
  1291. // A full textual representation of a month, such as January or March
  1292. dM = $.inArray(date[k], opts.monthNames, 12);
  1293. if (dM !== -1 && dM > 11) {
  1294. date[k] = dM + 1 - 12;
  1295. ts.m = date[k];
  1296. }
  1297. break;
  1298. case "n":
  1299. // Numeric representation of a month, without leading zeros 1 through 12
  1300. ts.m = parseInt(date[k], 10);
  1301. break;
  1302. case "j":
  1303. // Day of the month without leading zeros 1 to 31
  1304. ts.d = parseInt(date[k], 10);
  1305. break;
  1306. case "g":
  1307. // 12-hour format of an hour without leading zeros 1 through 12
  1308. ts.h = parseInt(date[k], 10);
  1309. break;
  1310. case "a":
  1311. // Lowercase Ante meridiem and Post meridiem am or pm
  1312. dM = $.inArray(date[k], opts.AmPm);
  1313. if (dM !== -1 && dM < 2 && date[k] === opts.AmPm[dM]) {
  1314. date[k] = dM;
  1315. ts.h = h12To24(date[k], ts.h);
  1316. }
  1317. break;
  1318. case "A":
  1319. // Uppercase Ante meridiem and Post meridiem AM or PM
  1320. dM = $.inArray(date[k], opts.AmPm);
  1321. if (dM !== -1 && dM > 1 && date[k] === opts.AmPm[dM]) {
  1322. date[k] = dM - 2;
  1323. ts.h = h12To24(date[k], ts.h);
  1324. }
  1325. break;
  1326. }
  1327. if (date[k] !== undefined && date[k] !== "" && !isNaN(date[k])) {
  1328. ts[format[k].toLowerCase()] = parseInt(date[k], 10);
  1329. }
  1330. }
  1331. if (ts.f) { ts.m = ts.f; }
  1332. if (ts.m === 0 && ts.y === 0 && ts.d === 0) {
  1333. return "&#160;";
  1334. }
  1335. ts.m = parseInt(ts.m, 10) - 1;
  1336. var ty = ts.y;
  1337. if (ty >= 70 && ty <= 99) {
  1338. ts.y = 1900 + ts.y;
  1339. } else if (ty >= 0 && ty <= 69) {
  1340. ts.y = 2000 + ts.y;
  1341. }
  1342. timestamp = new Date(ts.y, ts.m, ts.d, ts.h, ts.i, ts.s, ts.u);
  1343. //Apply offset to show date as local time.
  1344. if (offset !== 0) {
  1345. timestamp.setTime(Number(Number(timestamp) + (offset * 60 * 1000)));
  1346. }
  1347. }
  1348. } else {
  1349. timestamp = new Date(ts.y, ts.m, ts.d, ts.h, ts.i, ts.s, ts.u);
  1350. }
  1351. if (opts.userLocalTime && offset === 0) {
  1352. offset -= (new Date()).getTimezoneOffset();
  1353. if (offset !== 0) {
  1354. timestamp.setTime(Number(Number(timestamp) + (offset * 60 * 1000)));
  1355. }
  1356. }
  1357. if (newformat === undefined) {
  1358. return timestamp;
  1359. }
  1360. if (opts.masks.hasOwnProperty(newformat)) {
  1361. newformat = opts.masks[newformat];
  1362. } else if (!newformat) {
  1363. newformat = "Y-m-d";
  1364. }
  1365. if (newformat.toLowerCase() === "u1000") {
  1366. return timestamp.getTime();
  1367. }
  1368. var hours = timestamp.getHours(), // a Number, from 0 to 23, representing the hour
  1369. i = timestamp.getMinutes(),
  1370. j = timestamp.getDate(),
  1371. n = timestamp.getMonth() + 1,
  1372. o = timestamp.getTimezoneOffset(),
  1373. s = timestamp.getSeconds(),
  1374. u = timestamp.getMilliseconds(),
  1375. w = timestamp.getDay(),
  1376. year = timestamp.getFullYear(), // a Number, representing four digits, representing the year. Examples: 1999 or 2003
  1377. dayOfWeek = (w + 6) % 7 + 1, // numeric representation of the day of the week. 1 (for Monday) through 7 (for Sunday)
  1378. z = (new Date(year, n - 1, j) - new Date(year, 0, 1)) / 86400000,
  1379. weekNumberOfYear = dayOfWeek < 5 ?
  1380. Math.floor((z + dayOfWeek - 1) / 7) + 1 :
  1381. Math.floor((z + dayOfWeek - 1) / 7) || ((new Date(year - 1, 0, 1).getDay() + 6) % 7 < 4 ? 53 : 52),
  1382. flags = {
  1383. // Day
  1384. d: pad(j), // Day of the month, 2 digits with leading zeros 01 to 31
  1385. D: opts.dayNames[w], // A textual representation of a day, three letters. Mon through Sun
  1386. j: j, // Day of the month without leading zeros 1 to 31
  1387. l: opts.dayNames[w + 7], // A full textual representation of the day of the week. Sunday through Saturday
  1388. N: dayOfWeek, // ISO-8601 numeric representation of the day of the week. 1 (for Monday) through 7 (for Sunday)
  1389. S: opts.S(j), // English ordinal suffix for the day of the month, 2 characters. st, nd, rd or th. Works well with j
  1390. w: w, // Numeric representation of the day of the week. 0 (for Sunday) through 6 (for Saturday)
  1391. z: z, // The day of the year (starting from 0). 0 through 365
  1392. // Week.
  1393. W: weekNumberOfYear, // ISO-8601 week number of year, weeks starting on Monday. Example: 42 (the 42nd week in the year)
  1394. // Month
  1395. F: opts.monthNames[n - 1 + 12], // A full textual representation of a month, such as January or March. January through December
  1396. m: pad(n), // Numeric representation of a month, with leading zeros. 01 through 12
  1397. M: opts.monthNames[n - 1], // A short textual representation of a month, three letters. Jan through Dec
  1398. n: n, // Numeric representation of a month, without leading zeros. 1 through 12
  1399. t: "?", // Number of days in the given month. 28 through 31
  1400. // Year
  1401. L: "?", // Whether it's a leap year. 1 if it is a leap year, 0 otherwise.
  1402. o: "?", // SO-8601 year number. This has the same value as Y, except that if the ISO week number (W) belongs to the previous or next year, that year is used instead. Examples: 1999 or 2003
  1403. Y: year, // A full numeric representation of a year, 4 digits. Examples: 1999 or 2003
  1404. y: String(year).substring(2), // A two digit representation of a year. Examples: 99 or 03
  1405. // Time
  1406. a: hours < 12 ? opts.AmPm[0] : opts.AmPm[1], // Lowercase Ante meridiem and Post meridiem: am or pm
  1407. A: hours < 12 ? opts.AmPm[2] : opts.AmPm[3], // Uppercase Ante meridiem and Post meridiem: AM or PM
  1408. B: "?", // Swatch Internet time 000 through 999
  1409. g: hours % 12 || 12, // 12-hour format of an hour without leading zeros 1 through 12
  1410. G: hours, // 24-hour format of an hour without leading zeros. 0 through 23
  1411. h: pad(hours % 12 || 12), // 12-hour format of an hour with leading zeros: 01 through 12
  1412. H: pad(hours), // 24-hour format of an hour with leading zeros: 00 through 23
  1413. i: pad(i), // Minutes with leading zeros: 00 to 59
  1414. s: pad(s), // Seconds, with leading zeros: 00 through 59
  1415. u: u, // Microseconds. Example: 654321
  1416. // Timezone
  1417. e: "?", // Timezone identifier. Examples: UTC, GMT, Atlantic/Azores
  1418. I: "?", // Whether or not the date is in daylight saving time. 1 if Daylight Saving Time, 0 otherwise.
  1419. O: (o > 0 ? "-" : "+") + pad(Math.floor(Math.abs(o) / 60) * 100 + Math.abs(o) % 60, 4), // Difference to Greenwich time (GMT) in hours. Example: +0200
  1420. P: "?", // Difference to Greenwich time (GMT) with colon between hours and minutes. Example: +02:00
  1421. T: (String(timestamp).match(timezone) || [""]).pop().replace(timezoneClip, ""), // Timezone abbreviation. Examples: EST, MDT
  1422. Z: "?", // Timezone offset in seconds. The offset for timezones west of UTC is always negative, and for those east of UTC is always positive. -43200 through 50400
  1423. // Full Date/Time
  1424. c: "?", // ISO 8601 date. Example: 2004-02-12T15:19:21+00:00
  1425. r: "?", // RFC 2822 formatted date. Example: Thu, 21 Dec 2000 16:01:07 +0200
  1426. U: Math.floor(timestamp / 1000) // Seconds since the Unix Epoch (January 1 1970 00:00:00 GMT)
  1427. };
  1428. return newformat.replace(token, function ($0) {
  1429. return flags.hasOwnProperty($0) ? flags[$0] : $0.substring(1);
  1430. });
  1431. },
  1432. parseDateToNumber: function (format, date) {
  1433. var datetime = jgrid.parseDate.call(this, format, date);
  1434. // datetime could be the string "&#160;"
  1435. return datetime instanceof Date ? datetime.getTime() : 0;
  1436. },
  1437. jqID: function (sid) {
  1438. return String(sid).replace(/[!"#$%&'()*+,.\/:; <=>?@\[\\\]\^`{|}~]/g, "\\$&");
  1439. },
  1440. /**
  1441. * @param {COMPONENT_NAMES} componentName
  1442. */
  1443. getGridComponentId: function (componentName) {
  1444. var self = this;
  1445. if (self.p == null || !self.p.id) {
  1446. return ""; // return empty string
  1447. }
  1448. var id = self.p.id;
  1449. switch (componentName) {
  1450. case COMPONENT_NAMES.GRID:
  1451. return id;
  1452. case COMPONENT_NAMES.GRID_BOX_DIV:
  1453. return "gbox_" + id;
  1454. case COMPONENT_NAMES.GRID_VIEW_DIV:
  1455. return "gview_" + id;
  1456. case COMPONENT_NAMES.DIALOG_ALERT_DIV: // footer/summary table
  1457. return "alertmod_" + id;
  1458. case COMPONENT_NAMES.COLUMN_RESIZER_DIV:
  1459. return "rs_m" + id;
  1460. case COMPONENT_NAMES.HEADER_SELECT_ALL_ROWS_CHECKBOX:
  1461. return "cb_" + id;
  1462. case COMPONENT_NAMES.SEARCH_OPERATION_MENU_UL:
  1463. return "sopt_menu";
  1464. default:
  1465. return ""; // return empty string
  1466. }
  1467. },
  1468. /**
  1469. * @param {COMPONENT_NAMES} componentName
  1470. */
  1471. getGridComponentIdSelector: function (componentName) {
  1472. var id = jgrid.getGridComponentId.call(this, componentName);
  1473. return id ? "#" + jgrid.jqID(id) : "";
  1474. },
  1475. isHTMLElement: function (elem) {
  1476. // see http://stackoverflow.com/a/384380/315935
  1477. return (typeof HTMLElement === "object" || typeof HTMLElement === "function") ?
  1478. elem instanceof HTMLElement : //DOM2
  1479. elem != null && typeof elem === "object" && elem.nodeType === 1 && typeof elem.nodeName === "string";
  1480. },
  1481. /**
  1482. * @param {COMPONENT_NAMES} componentName
  1483. */
  1484. getGridComponent: function (componentName, $p) {// , p1
  1485. var p;
  1486. if ($p instanceof $ || $p.length > 0) {
  1487. p = $p[0];
  1488. } else if (jgrid.isHTMLElement($p)) {
  1489. p = $p;
  1490. $p = $(p);
  1491. } else {
  1492. return $(); // return empty jQuery object
  1493. }
  1494. switch (componentName) {
  1495. case COMPONENT_NAMES.BODY_TABLE: // get body table from bDiv
  1496. return $p.hasClass("ui-jqgrid-bdiv") ? $p.children("div").children(".ui-jqgrid-btable") : $();
  1497. case COMPONENT_NAMES.HEADER_TABLE: // header table from bDiv
  1498. return $p.hasClass("ui-jqgrid-hdiv") ? $p.children("div").children(".ui-jqgrid-htable") : $();
  1499. case COMPONENT_NAMES.FOOTER_TABLE: // footer/summary table from sDiv
  1500. return $p.hasClass("ui-jqgrid-sdiv") ? $p.children("div").children(".ui-jqgrid-ftable") : $();
  1501. case COMPONENT_NAMES.FROZEN_HEADER_TABLE: // header table from bDiv
  1502. return $p.hasClass("ui-jqgrid-hdiv") ? $p.children(".ui-jqgrid-htable") : $();
  1503. case COMPONENT_NAMES.FROZEN_FOOTER_TABLE: // footer/summary table from sDiv
  1504. return $p.hasClass("ui-jqgrid-sdiv") ? $p.children(".ui-jqgrid-ftable") : $();
  1505. case COMPONENT_NAMES.BODY_DIV: // get bDiv of grid (bTable)
  1506. return $p.hasClass("ui-jqgrid-btable") && p.grid != null ? $(p.grid.bDiv) : $();
  1507. case COMPONENT_NAMES.HEADER_DIV: // get hDiv of grid (bTable)
  1508. return $p.hasClass("ui-jqgrid-btable") && p.grid != null ? $(p.grid.hDiv) : $();
  1509. case COMPONENT_NAMES.FOOTER_DIV: // get sDiv of grid (bTable)
  1510. return $p.hasClass("ui-jqgrid-btable") && p.grid != null ? $(p.grid.sDiv) : $();
  1511. //case "colHeader": // p should be iCol
  1512. // return !isNaN(p1) && p.grid != null && p.grid.headers != null && p.grid.headers[p1] != null ?
  1513. // $(p.grid.headers[p1].el) : $();
  1514. default:
  1515. return $(); // return empty jQuery object
  1516. }
  1517. },
  1518. fixScrollOffsetAndhBoxPadding: function () {
  1519. var self = this, grid = self.grid;
  1520. if (!grid) {
  1521. return;
  1522. }
  1523. var p = self.p, bDiv = grid.bDiv,
  1524. fixhBox = function (hDiv) {
  1525. var $hDivhBox = $(hDiv).children("div").first();
  1526. $hDivhBox.css($hDivhBox.hasClass("ui-jqgrid-hbox-rtl") ? "padding-left" : "padding-right", p.scrollOffset);
  1527. hDiv.scrollLeft = bDiv.scrollLeft;
  1528. };
  1529. if ($(bDiv).width() > 0) {
  1530. p.scrollOffset = (bDiv.offsetWidth - bDiv.clientWidth); // can be 0 if no scrollbar exist
  1531. // TODO: add detection of the width of vertical scroll bar if the grid is hidden
  1532. // at the moment of executing fixScrollOffsetAndhBoxPadding (for example inside of inactive jQuery UI Tab)
  1533. // one need just create close construction with visible:hidden style, add to body and get its width
  1534. fixhBox(grid.hDiv);
  1535. if (grid.sDiv) {
  1536. fixhBox(grid.sDiv);
  1537. }
  1538. }
  1539. },
  1540. mergeCssClasses: function () {
  1541. var args = $.makeArray(arguments), map = {}, i, j, ar, cssClass, classes = [];
  1542. for (i = 0; i < args.length; i++) {
  1543. ar = String(args[i]).replace(/[\t\r\n\f]/g, " ").split(" ");
  1544. for (j = 0; j < ar.length; j++) {
  1545. cssClass = ar[j];
  1546. if (cssClass !== "" && !map.hasOwnProperty(cssClass)) {
  1547. map[cssClass] = true;
  1548. classes.push(cssClass);
  1549. }
  1550. }
  1551. }
  1552. return classes.join(" ");
  1553. },
  1554. hasOneFromClasses: function (elem, classes) {
  1555. var $elem = $(elem),
  1556. arClasses = String(classes).replace(/[\t\r\n\f]/g, " ").split(" "),
  1557. n = arClasses.length,
  1558. i;
  1559. for (i = 0; i < n; i++) {
  1560. if ($elem.hasClass(arClasses[i])) {
  1561. return true;
  1562. }
  1563. }
  1564. return false;
  1565. },
  1566. hasAllClasses: function (elem, classes) {
  1567. // the current implementation of jQuery.hasClass can work with multiple classes,
  1568. // but the classes HAVE TO BE in exact the same order. jQuery.hasClass just
  1569. // search for classes using indexOf.
  1570. // (see https://github.com/jquery/jquery/blob/1.11.3/src/attributes/classes.js#L143-L154)
  1571. // Thus we cant's use it to test whether an element has the list of all the classes
  1572. // and we introduces the helper method hasAllClasses
  1573. var $elem = $(elem),
  1574. arClasses = String(classes).replace(/[\t\r\n\f]/g, " ").split(" "),
  1575. n = arClasses.length,
  1576. i;
  1577. for (i = 0; i < n; i++) {
  1578. if (!$elem.hasClass(arClasses[i])) {
  1579. return false;
  1580. }
  1581. }
  1582. return true;
  1583. },
  1584. detectRowEditing: function (rowid) {
  1585. //var i, savedRowInfo, tr, self = this, rows = self.rows, p = self.p, isFunction = $.isFunction;
  1586. if (!this.grid || this.p == null || this.p.editingInfo == null || this.p.editingInfo[rowid] == null) {
  1587. return null; // this is not a grid or the row is not editing now
  1588. }
  1589. return this.p.editingInfo[rowid];
  1590. },
  1591. // The method returns jQuery wrapper with the cell (<td>) of the row.
  1592. // It can return jQuery wrapper with two cells in case of usage frozen data:
  1593. // one cell of the main grid and another cell with the corresponding cell from the frozen body table
  1594. getCell: function (tr, iCol) {
  1595. var grid = this.grid, p = this.p, frozenRows, $td;
  1596. if (!grid || !p) { return $(); } // not a grid
  1597. if (tr instanceof $ || tr.length > 0) {
  1598. tr = tr[0]; // unwrap jQuery object to DOM element
  1599. }
  1600. if (!((typeof HTMLTableRowElement === "object" || typeof HTMLTableRowElement === "function") && tr instanceof HTMLTableRowElement) || tr.cells == null) { // the line will be failed in IE7
  1601. return $(); // return empty jQuery object
  1602. }
  1603. $td = $(tr.cells[iCol]);
  1604. frozenRows = grid.fbRows;
  1605. return frozenRows != null && iCol < frozenRows[0].cells.length ?
  1606. $td.add(frozenRows[tr.rowIndex].cells[iCol]) :
  1607. $td;
  1608. },
  1609. getDataFieldOfCell: function (tr, iCol) {
  1610. var p = this.p, $td = jgrid.getCell.call(this, tr, iCol), $dataElement;
  1611. if (p.treeGrid && $td.children("div.tree-wrap").length > 0) {
  1612. $td = $td.children("span.cell-wrapperleaf,span.cell-wrapper");
  1613. }
  1614. if (p.colModel[iCol].autoResizable) {
  1615. $dataElement = $td.children("span." + p.autoResizing.wrapperClassName);
  1616. if ($dataElement.length === 0) { // for example, td is in editing mode
  1617. $dataElement = $td;
  1618. }
  1619. } else {
  1620. $dataElement = $td;
  1621. }
  1622. return $dataElement;
  1623. },
  1624. enumEditableCells: function (tr, mode, callback) {
  1625. var self = this, grid = self.grid, rows = self.rows, p = self.p;
  1626. if (grid == null || rows == null || p == null || tr == null || tr.rowIndex == null || !tr.id || !$.isFunction(callback)) {
  1627. return null; // this is not a grid or tr is not tr
  1628. }
  1629. var iCol, colModel = p.colModel, nCol = colModel.length, cm, nm, options, id, pos, item,
  1630. isEditable, iRow = tr.rowIndex, td, $dataElement, dataWidth,
  1631. frozenRows = grid.fbRows, frozen = frozenRows != null,
  1632. trFrozen = frozen ? frozenRows[iRow] : null;
  1633. // normalize tr if required
  1634. if (frozen/* && !$.contains(self, tr)*/) {
  1635. // The event could be inside of frozen div.
  1636. // Thus tr could be the same as trFrozen
  1637. // We normalize it based on the rowIndex.
  1638. tr = self.rows[iRow];
  1639. }
  1640. for (iCol = 0; iCol < nCol; iCol++) {
  1641. cm = colModel[iCol];
  1642. nm = cm.name;
  1643. if (nm !== "cb" && nm !== "subgrid" && nm !== "rn") {
  1644. if (frozen && !cm.frozen) {
  1645. frozen = false;
  1646. }
  1647. td = (frozen ? trFrozen : tr).cells[iCol];
  1648. $dataElement = $(td);
  1649. if (!$dataElement.hasClass("not-editable-cell")) {
  1650. dataWidth = $dataElement.width();
  1651. if (p.treeGrid === true && nm === p.ExpandColumn) {
  1652. dataWidth -= $dataElement.children("div.tree-wrap").outerWidth();
  1653. $dataElement = $dataElement.children("span.cell-wrapperleaf,span.cell-wrapper").first();
  1654. } else {
  1655. dataWidth = 0; // we can test it in the callback and use width:auto in the case
  1656. }
  1657. id = stripPref(p.idPrefix, tr.id);
  1658. options = {
  1659. rowid: tr.id,
  1660. id: id,
  1661. iCol: iCol,
  1662. iRow: iRow,
  1663. cmName: nm,
  1664. cm: cm,
  1665. mode: mode,
  1666. td: td,
  1667. tr: tr,
  1668. trFrozen: trFrozen,
  1669. dataElement: $dataElement[0],
  1670. dataWidth: dataWidth
  1671. };
  1672. if (p.datatype === "local") {
  1673. pos = p._index[id];
  1674. item = pos != null ? p.data[pos] : undefined;
  1675. if (item) {
  1676. options.item = item;
  1677. }
  1678. }
  1679. if (!cm.edittype) { cm.edittype = "text"; }
  1680. if (((p.editingInfo[tr.id] || {}).editable || {}).hasOwnProperty(nm)) {
  1681. // if the cell in already editing
  1682. isEditable = p.editingInfo[tr.id].editable[nm];
  1683. } else {
  1684. isEditable = cm.editable;
  1685. isEditable = $.isFunction(isEditable) ?
  1686. isEditable.call(self, options) :
  1687. isEditable;
  1688. }
  1689. if (isEditable === true || isEditable === "hidden") {
  1690. options.editable = isEditable;
  1691. if (callback.call(self, options) === false) { break; }
  1692. }
  1693. }
  1694. }
  1695. }
  1696. },
  1697. getEditedValue: function ($dataFiled, cm, valueText, editable) {
  1698. var result, checkBoxValues, newformat, $field, values, texts,
  1699. formatoptions = cm.formatoptions || {}, editoptions = cm.editoptions || {},
  1700. customValue = editoptions.custom_value,
  1701. nameSelector = "[name=" + jgrid.jqID(cm.name) + "]", $t = this, $self = $($t);
  1702. if (editable === "hidden" || editable === "readonly") {
  1703. // the implementation from the next line can be improved
  1704. return $($t).jqGrid("getCell", $dataFiled.closest("tr.jqgrow").attr("id"), cm.name);
  1705. }
  1706. switch (cm.edittype) {
  1707. case "checkbox":
  1708. checkBoxValues = ["Yes", "No"];
  1709. if (typeof editoptions.value === "string") {
  1710. checkBoxValues = editoptions.value.split(":");
  1711. }
  1712. result = $dataFiled.find("input[type=checkbox]").is(":checked") ? checkBoxValues[0] : checkBoxValues[1];
  1713. break;
  1714. case "text":
  1715. case "password":
  1716. case "textarea":
  1717. case "button":
  1718. $field = $dataFiled.find("input" + nameSelector + ",textarea" + nameSelector);
  1719. result = $field.val();
  1720. if ($field.prop("type") === "date" && String(result).split("-").length === 3) {
  1721. newformat = formatoptions.newformat || $self.jqGrid("getGridRes", "formatter.date.newformat");
  1722. result = jgrid.parseDate.call($t, "Y-m-d", result, newformat);
  1723. }
  1724. break;
  1725. case "select":
  1726. $field = $dataFiled.find("select option:selected");
  1727. if (editoptions.multiple) {
  1728. values = [];
  1729. texts = [];
  1730. $field.each(function () {
  1731. values.push($(this).val());
  1732. texts.push($(this).text());
  1733. });
  1734. result = values.join(",");
  1735. valueText.text = texts.join(",");
  1736. } else {
  1737. result = $field.val();
  1738. valueText.text = $field.text();
  1739. }
  1740. valueText.value = result;
  1741. break;
  1742. case "custom":
  1743. try {
  1744. if ($.isFunction(customValue)) {
  1745. result = customValue.call($t, $dataFiled.find(".customelement"), "get");
  1746. if (result === undefined) {
  1747. throw "e2";
  1748. }
  1749. } else {
  1750. throw "e1";
  1751. }
  1752. } catch (e) {
  1753. var errorText, infoDialog = jgrid.info_dialog,
  1754. getRes = function (path) { $self.jqGrid("getGridRes", path); };
  1755. switch (String(e)) {
  1756. case "e1":
  1757. errorText = "function 'custom_value' " + getRes("edit.msg.nodefined");
  1758. break;
  1759. case "e2":
  1760. break;
  1761. default:
  1762. errorText = e.message;
  1763. break;
  1764. }
  1765. if (infoDialog && $.isFunction(infoDialog)) {
  1766. infoDialog.call($t, getRes("errors.errcap"), errorText, getRes("edit.bClose"));
  1767. } else {
  1768. ($.isFunction(defaults.fatalError) ? defaults.fatalError : alert)(errorText);
  1769. }
  1770. }
  1771. break;
  1772. default:
  1773. result = $dataFiled.find("*" + nameSelector).text();
  1774. break;
  1775. }
  1776. return result;
  1777. },
  1778. guid: 1,
  1779. uidPref: "jqg",
  1780. randId: function (prefix) {
  1781. return (prefix || jgrid.uidPref) + (jgrid.guid++);
  1782. },
  1783. getAccessor: function (obj, expr) {
  1784. var ret, p, prm = [], i;
  1785. if ($.isFunction(expr)) { return expr(obj); }
  1786. if (obj != null && obj.hasOwnProperty(expr)) {
  1787. return obj[expr];
  1788. }
  1789. try {
  1790. if (typeof expr === "string") {
  1791. prm = expr.split(".");
  1792. }
  1793. i = prm.length;
  1794. if (i) {
  1795. ret = obj;
  1796. while (ret != null && i--) {
  1797. p = prm.shift();
  1798. if (ret.hasOwnProperty(p)) {
  1799. ret = ret[p];
  1800. } else {
  1801. ret = undefined;
  1802. }
  1803. }
  1804. }
  1805. } catch (ignore) { }
  1806. return ret;
  1807. },
  1808. getXmlData: function (obj, expr, returnObj) {
  1809. var m = typeof expr === "string" ? expr.match(/^(.*)\[(\w+)\]$/) : null;
  1810. if ($.isFunction(expr)) { return expr(obj); }
  1811. if (m && m[2]) {
  1812. // m[2] is the attribute selector
  1813. // m[1] is an optional element selector
  1814. // examples: "[id]", "rows[page]"
  1815. return m[1] ? $(m[1], obj).attr(m[2]) : $(obj).attr(m[2]);
  1816. }
  1817. if (obj === undefined) {
  1818. //alert("expr");
  1819. return undefined;
  1820. }
  1821. // !!! one should never use another form $(expr, obj) if obj could be undefined
  1822. // In the case the $(expr, obj) could be $("someString") and jQuery can
  1823. // parse it as array of characters ($("someString").length will be "someString".length) !!!
  1824. // The problem take place if expr is not string object, but object new String("someString").
  1825. // The problem can exist if one use $.each with array of strings.
  1826. // The "this" inside of $.each is the string converted to object.
  1827. var ret = $(obj).find(expr);
  1828. if (returnObj) { return ret; }
  1829. //$(expr, obj).filter(":last"); // we use ":last" to be more compatible with old version of jqGrid
  1830. return ret.length > 0 ? $(ret).text() : undefined;
  1831. },
  1832. cellWidth: function () {
  1833. // TODO: use all other classes in grid. Probably one should set the visibility explicitly to show (display:block)
  1834. var $testDiv = $("<div class='ui-jqgrid' style='left:10000px'><div class='ui-jqgrid-view'><div class='ui-jqgrid-bdiv'><table class='ui-jqgrid-btable' style='width:5px;'><tr class='jqgrow'><td style='width:5px;display:block;'></td></tr></table></div></div></div>"),
  1835. testCell = $testDiv.appendTo("body")
  1836. .find("td")
  1837. .width();
  1838. $testDiv.remove();
  1839. return Math.abs(testCell - 5) > 0.1;
  1840. },
  1841. isCellClassHidden: function (className) {
  1842. if (className == null || className === "") {
  1843. return false;
  1844. } else {
  1845. var $testDiv = $("<div class='ui-jqgrid' style='left:10000px'><div class='ui-jqgrid-view'><div class='ui-jqgrid-bdiv'><table class='ui-jqgrid-btable' style='width:5px;'><tr class='jqgrow'><td style='width:5px;' class='" + (className || "") + "'></td></tr></table></div></div></div>"),
  1846. isHidden = $testDiv.appendTo("body")
  1847. .find("td")
  1848. .is(":hidden");
  1849. $testDiv.remove();
  1850. return isHidden;
  1851. }
  1852. },
  1853. cell_width: true,
  1854. ajaxOptions: {},
  1855. from: function (source) {
  1856. // Original Author Hugo Bonacci
  1857. // License MIT http://jlinq.codeplex.com/license
  1858. var context = this,
  1859. /**
  1860. * @private
  1861. * @class
  1862. */
  1863. QueryObject = function (d, q) {
  1864. var self = this,
  1865. _data = d,
  1866. _usecase = true,
  1867. _trim = false,
  1868. _query = q,
  1869. _stripNum = /[\$,%]/g,
  1870. _lastCommand = null,
  1871. _lastField = null,
  1872. _orDepth = 0,
  1873. _negate = false,
  1874. _queuedOperator = "",
  1875. _sorting = [],
  1876. toString = Object.prototype.toString;
  1877. if (typeof d === "object" && d.push) {
  1878. if (d.length > 0) {
  1879. if (typeof d[0] !== "object") {
  1880. throw "data items are not objects";
  1881. }
  1882. }
  1883. } else {
  1884. throw "data provides is not an array";
  1885. }
  1886. /**
  1887. * @private
  1888. * @type {function(): boolean}
  1889. */
  1890. this._hasData = function () {
  1891. return _data === null ? false : _data.length === 0 ? false : true;
  1892. };
  1893. /**
  1894. * @private
  1895. * @type {function(string): string}
  1896. */
  1897. this._getStr = function (s) {
  1898. var phrase = [];
  1899. if (_trim) {
  1900. phrase.push("jQuery.trim(");
  1901. }
  1902. phrase.push("String(" + s + " || '')");
  1903. if (_trim) {
  1904. phrase.push(")");
  1905. }
  1906. if (!_usecase) {
  1907. phrase.push(".toUpperCase()");
  1908. }
  1909. return phrase.join("");
  1910. };
  1911. /** @private */
  1912. this._strComp = function (val) {
  1913. if (typeof val === "string") {
  1914. return ".toString()";
  1915. }
  1916. return "";
  1917. };
  1918. /** @private */
  1919. this._group = function (f, u) {
  1920. return ({ field: f.toString(), unique: u, items: [] });
  1921. };
  1922. /** @private */
  1923. this._toStr = function (phrase) {
  1924. if (_trim) {
  1925. phrase = $.trim(phrase);
  1926. }
  1927. phrase = phrase.toString().replace(/\\/g, "\\\\").replace(/"/g, "\\\"");
  1928. return _usecase ? phrase : phrase.toUpperCase();
  1929. };
  1930. /** @private */
  1931. this._funcLoop = function (func) {
  1932. var results = [];
  1933. $.each(_data, function (i, v) {
  1934. results.push(func(v));
  1935. });
  1936. return results;
  1937. };
  1938. /** @private */
  1939. this._append = function (s) {
  1940. var i;
  1941. if (_query === null) {
  1942. _query = "";
  1943. } else {
  1944. _query += _queuedOperator === "" ? " && " : _queuedOperator;
  1945. }
  1946. for (i = 0; i < _orDepth; i++) {
  1947. _query += "(";
  1948. }
  1949. if (_negate) {
  1950. _query += "!";
  1951. }
  1952. _query += "(" + s + ")";
  1953. _negate = false;
  1954. _queuedOperator = "";
  1955. _orDepth = 0;
  1956. };
  1957. /** @private */
  1958. this._setCommand = function (f, c) {
  1959. _lastCommand = f;
  1960. _lastField = c;
  1961. };
  1962. /** @private */
  1963. this._resetNegate = function () {
  1964. _negate = false;
  1965. };
  1966. /** @private */
  1967. this._repeatCommand = function (f, v) {
  1968. if (_lastCommand === null) {
  1969. return self;
  1970. }
  1971. if (f !== null && v !== null) {
  1972. return _lastCommand(f, v);
  1973. }
  1974. if (_lastField === null) {
  1975. return _lastCommand(f);
  1976. }
  1977. return _lastCommand(_lastField, f);
  1978. };
  1979. /** @private */
  1980. this._equals = function (a, b) {
  1981. return (self._compare(a, b, 1) === 0);
  1982. };
  1983. /** @private */
  1984. this._compare = function (a, b, dir) {
  1985. if (dir === undefined) { dir = 1; }
  1986. if (a === undefined) { a = null; }
  1987. if (b === undefined) { b = null; }
  1988. if (a === null && b === null) {
  1989. return 0;
  1990. }
  1991. if (a === null && b !== null) {
  1992. return 1;
  1993. }
  1994. if (a !== null && b === null) {
  1995. return -1;
  1996. }
  1997. if (toString.call(a) === "[object Date]" && toString.call(b) === "[object Date]") {
  1998. if (a < b) { return -dir; }
  1999. if (a > b) { return dir; }
  2000. return 0;
  2001. }
  2002. if (!_usecase && typeof a !== "number" && typeof b !== "number") {
  2003. a = String(a);
  2004. b = String(b);
  2005. }
  2006. if (a < b) { return -dir; }
  2007. if (a > b) { return dir; }
  2008. return 0;
  2009. };
  2010. /** @private */
  2011. this._performSort = function () {
  2012. if (_sorting.length === 0) { return; }
  2013. _data = self._doSort(_data, 0);
  2014. };
  2015. /** @private */
  2016. this._doSort = function (data, iSort) {
  2017. var by = _sorting[iSort].by,
  2018. dir = _sorting[iSort].dir,
  2019. type = _sorting[iSort].type,
  2020. dfmt = _sorting[iSort].datefmt,
  2021. sfunc = _sorting[iSort].sfunc;
  2022. if (iSort === _sorting.length - 1) {
  2023. return self._getOrder(data, by, dir, type, dfmt, sfunc);
  2024. }
  2025. iSort++;
  2026. var values = self._getGroup(data, by, dir, type, dfmt), results = [], i, j, sorted;
  2027. for (i = 0; i < values.length; i++) {
  2028. sorted = self._doSort(values[i].items, iSort);
  2029. for (j = 0; j < sorted.length; j++) {
  2030. results.push(sorted[j]);
  2031. }
  2032. }
  2033. return results;
  2034. };
  2035. /** @private */
  2036. this._getOrder = function (data, by, dir, type, dfmt, sfunc) {
  2037. var sortData = [], _sortData = [], newDir = dir === "a" ? 1 : -1, i, ab, findSortKey;
  2038. if (type === undefined) { type = "text"; }
  2039. if (type === "float" || type === "number" || type === "currency" || type === "numeric") {
  2040. findSortKey = function ($cell) {
  2041. var key = parseFloat(String($cell).replace(_stripNum, ""));
  2042. return isNaN(key) ? Number.NEGATIVE_INFINITY : key;
  2043. };
  2044. } else if (type === "int" || type === "integer") {
  2045. findSortKey = function ($cell) {
  2046. return $cell != null ? parseFloat(String($cell).replace(_stripNum, "")) : Number.NEGATIVE_INFINITY;
  2047. };
  2048. } else if (type === "date" || type === "datetime") {
  2049. findSortKey = function ($cell) {
  2050. return jgrid.parseDateToNumber.call(context, dfmt, $cell);
  2051. };
  2052. } else if ($.isFunction(type)) {
  2053. findSortKey = type;
  2054. } else {
  2055. findSortKey = function ($cell) {
  2056. $cell = $cell != null ? $.trim(String($cell)) : "";
  2057. return _usecase ? $cell : $cell.toUpperCase();
  2058. };
  2059. }
  2060. $.each(data, function (index, v) {
  2061. ab = by !== "" ? jgrid.getAccessor(v, by) : v;
  2062. if (ab === undefined) { ab = ""; }
  2063. ab = findSortKey.call(context, ab, v);
  2064. _sortData.push({ vSort: ab, data: v, index: index });
  2065. });
  2066. if ($.isFunction(sfunc)) {
  2067. _sortData.sort(function (a, b) {
  2068. return sfunc.call(context, a.vSort, b.vSort, newDir, a.data, b.data);
  2069. });
  2070. } else {
  2071. _sortData.sort(function (a, b) {
  2072. return self._compare(a.vSort, b.vSort, newDir);
  2073. });
  2074. }
  2075. var j = 0, nrec = data.length;
  2076. // overhead, but we do not change the original data.
  2077. while (j < nrec) {
  2078. i = _sortData[j].index;
  2079. sortData.push(data[i]);
  2080. j++;
  2081. }
  2082. return sortData;
  2083. };
  2084. /** @private */
  2085. this._getGroup = function (data, by, dir, type, dfmt) {
  2086. var results = [],
  2087. group = null,
  2088. last = null;
  2089. $.each(self._getOrder(data, by, dir, type, dfmt), function (i, v) {
  2090. var val = jgrid.getAccessor(v, by);
  2091. if (val == null) { val = ""; }
  2092. if (!self._equals(last, val)) {
  2093. last = val;
  2094. if (group !== null) {
  2095. results.push(group);
  2096. }
  2097. group = self._group(by, val);
  2098. }
  2099. group.items.push(v);
  2100. });
  2101. if (group !== null) {
  2102. results.push(group);
  2103. }
  2104. return results;
  2105. };
  2106. this.ignoreCase = function () {
  2107. _usecase = false;
  2108. return self;
  2109. };
  2110. this.useCase = function () {
  2111. _usecase = true;
  2112. return self;
  2113. };
  2114. this.trim = function () {
  2115. _trim = true;
  2116. return self;
  2117. };
  2118. this.noTrim = function () {
  2119. _trim = false;
  2120. return self;
  2121. };
  2122. this.execute = function () {
  2123. var match = _query, results = [];
  2124. if (match === null) {
  2125. return self;
  2126. }
  2127. $.each(_data, function () {
  2128. (function () {
  2129. var localMath = "(function (context) {\n" +
  2130. "var yesObject = { 1: 1, x: 1, \"true\": 1, yes: 1, y: 1, on: 1 }," +
  2131. "noObject = { 0: 1, \"false\": 1, no: 1, n: 1, off: 1 }," +
  2132. "normilizeBoolean = function (v) {\n" +
  2133. "if (typeof v === \"string\") {\n" +
  2134. "if (noObject[v.toLowerCase()]) { return false; } " +
  2135. "else if (yesObject[v.toLowerCase()]) { return true; } " +
  2136. "}\n" +
  2137. "return !!v;\n" +
  2138. "}," +
  2139. "intFunc = function (jQuery, self) { return " +
  2140. match +
  2141. "; }; return intFunc.call(context.item, context.jQuery, context.context); }(this))";
  2142. if (eval(localMath)) { results.push(this.item); }
  2143. }.call({
  2144. item: this,
  2145. jQuery: $,
  2146. context: context
  2147. }));
  2148. });
  2149. _data = results;
  2150. return self;
  2151. };
  2152. this.data = function () {
  2153. return _data;
  2154. };
  2155. this.select = function (f) {
  2156. self.execute();
  2157. if ($.isFunction(f)) {
  2158. var results = [];
  2159. $.each(_data, function (i, v) {
  2160. results.push(f(v));
  2161. });
  2162. return results;
  2163. }
  2164. if (!self._hasData()) { return []; }
  2165. self._performSort();
  2166. return _data;
  2167. };
  2168. this.hasMatch = function () {
  2169. if (!self._hasData()) { return false; }
  2170. self.execute();
  2171. return _data.length > 0;
  2172. };
  2173. this.andNot = function (f, v, x) {
  2174. _negate = !_negate;
  2175. return self.and(f, v, x);
  2176. };
  2177. this.orNot = function (f, v, x) {
  2178. _negate = !_negate;
  2179. return self.or(f, v, x);
  2180. };
  2181. this.not = function (f, v, x) {
  2182. return self.andNot(f, v, x);
  2183. };
  2184. this.and = function (f, v, x) {
  2185. _queuedOperator = " && ";
  2186. if (f === undefined) {
  2187. return self;
  2188. }
  2189. return self._repeatCommand(f, v, x);
  2190. };
  2191. this.or = function (f, v, x) {
  2192. _queuedOperator = " || ";
  2193. if (f === undefined) { return self; }
  2194. return self._repeatCommand(f, v, x);
  2195. };
  2196. this.orBegin = function () {
  2197. _orDepth++;
  2198. return self;
  2199. };
  2200. this.orEnd = function () {
  2201. if (_query !== null) {
  2202. _query += ")";
  2203. }
  2204. return self;
  2205. };
  2206. this.isNot = function (f) {
  2207. _negate = !_negate;
  2208. return self.is(f);
  2209. };
  2210. this.is = function (f) {
  2211. self._append("this." + f);
  2212. self._resetNegate();
  2213. return self;
  2214. };
  2215. /** @private */
  2216. this._compareValues = function (func, f, v, how, t) {
  2217. var fld = f;
  2218. if (v === undefined) { v = null; }
  2219. //var val=v===null?f:v,
  2220. var val = v, swst = t.stype === undefined ? "text" : t.stype;
  2221. if (v !== null) {
  2222. switch (swst) {
  2223. case "int":
  2224. case "integer":
  2225. val = String(val).replace(_stripNum, "");
  2226. val = (isNaN(Number(val)) || val === "") ? "0" : Number(val); // To be fixed with more intelligent code
  2227. fld = "parseInt(" + fld + "||0,10)";
  2228. val = String(parseInt(val, 10));
  2229. break;
  2230. case "boolean":
  2231. // use !! operator to convert ruthy/falsy values to boolean and then compare the values
  2232. fld = "normilizeBoolean(" + fld + ")";
  2233. val = "normilizeBoolean(" + String(val) + ")";
  2234. break;
  2235. case "float":
  2236. case "number":
  2237. case "currency":
  2238. case "numeric":
  2239. val = String(val).replace(_stripNum, "");
  2240. val = (isNaN(Number(val)) || val === "") ? "0" : Number(val); // To be fixed with more intelligent code
  2241. fld = "parseFloat(" + fld + "||0)";
  2242. val = String(val);
  2243. break;
  2244. case "date":
  2245. case "datetime":
  2246. val = String(jgrid.parseDateToNumber.call(context, t.newfmt || "Y-m-d", val));
  2247. fld = "jQuery.jgrid.parseDateToNumber.call(self,\"" + t.srcfmt + "\"," + fld + ")";
  2248. break;
  2249. default:
  2250. // TODO: consider to apply formatter at least to process correctly
  2251. // default values. For example is bootean property is not defined
  2252. // if will be displayed by formatter:"checkbox" as false value.
  2253. // If the user search for the value one will process the following
  2254. // jQuery.jgrid.getAccessor(this,'closed')).toUpperCase() == String("FALSE").toUpperCase()
  2255. // which works wrong if the property "closed" is undefined.
  2256. fld = self._getStr(fld);
  2257. val = self._getStr("\"" + self._toStr(val) + "\"");
  2258. }
  2259. }
  2260. self._append(fld + " " + how + " " + val);
  2261. self._setCommand(func, f);
  2262. self._resetNegate();
  2263. return self;
  2264. };
  2265. this.equals = function (f, v, t) {
  2266. return self._compareValues(self.equals, f, v, "==", t);
  2267. };
  2268. this.notEquals = function (f, v, t) {
  2269. return self._compareValues(self.equals, f, v, "!==", t);
  2270. };
  2271. this.isNull = function (f, v, t) {
  2272. return self._compareValues(self.equals, f, null, "===", t);
  2273. };
  2274. this.greater = function (f, v, t) {
  2275. return self._compareValues(self.greater, f, v, ">", t);
  2276. };
  2277. this.less = function (f, v, t) {
  2278. return self._compareValues(self.less, f, v, "<", t);
  2279. };
  2280. this.greaterOrEquals = function (f, v, t) {
  2281. return self._compareValues(self.greaterOrEquals, f, v, ">=", t);
  2282. };
  2283. this.lessOrEquals = function (f, v, t) {
  2284. return self._compareValues(self.lessOrEquals, f, v, "<=", t);
  2285. };
  2286. this.startsWith = function (f, v) {
  2287. var val = (v == null) ? f : v,
  2288. length = _trim ? $.trim(val.toString()).length : val.toString().length;
  2289. self._append(self._getStr(f) + ".substr(0," + length + ") == " + self._getStr("\"" + self._toStr(v) + "\""));
  2290. self._setCommand(self.startsWith, f);
  2291. self._resetNegate();
  2292. return self;
  2293. };
  2294. this.endsWith = function (f, v) {
  2295. var val = (v == null) ? f : v,
  2296. length = _trim ? $.trim(val.toString()).length : val.toString().length;
  2297. self._append(self._getStr(f) + ".substr(" + self._getStr(f) + ".length-" + length + "," + length + ") == \"" + self._toStr(v) + "\"");
  2298. self._setCommand(self.endsWith, f);
  2299. self._resetNegate();
  2300. return self;
  2301. };
  2302. this.contains = function (f, v) {
  2303. self._append(self._getStr(f) + ".indexOf(\"" + self._toStr(v) + "\",0) > -1");
  2304. self._setCommand(self.contains, f);
  2305. self._resetNegate();
  2306. return self;
  2307. };
  2308. this.groupBy = function (by, dir, type, datefmt) {
  2309. if (!self._hasData()) {
  2310. return null;
  2311. }
  2312. return self._getGroup(_data, by, dir, type, datefmt);
  2313. };
  2314. this.orderBy = function (by, dir, stype, dfmt, sfunc) {
  2315. dir = dir == null ? "a" : $.trim(dir.toString().toLowerCase());
  2316. if (stype == null) { stype = "text"; }
  2317. if (dfmt == null) { dfmt = "Y-m-d"; }
  2318. if (sfunc == null) { sfunc = false; }
  2319. if (dir === "desc" || dir === "descending") { dir = "d"; }
  2320. if (dir === "asc" || dir === "ascending") { dir = "a"; }
  2321. _sorting.push({ by: by, dir: dir, type: stype, datefmt: dfmt, sfunc: sfunc });
  2322. return self;
  2323. };
  2324. this.inSet = function (f, v, t) {
  2325. var val = v === undefined ? null : v,
  2326. swst = t.stype === undefined ? "text" : t.stype;
  2327. val = self._getStr("\"" + self._toStr(val) + "\"");
  2328. if (swst !== "text") {
  2329. // NOT yet implemented
  2330. return self._compareValues(self.equals, f, v, "==", t);
  2331. }
  2332. self._append("jQuery.inArray(" + self._getStr(f) + "," + val + ".split('" +
  2333. (context.p.inFilterSeparator || ",") + "')) >= 0");
  2334. self._setCommand(self.inSet, f);
  2335. self._resetNegate();
  2336. return self;
  2337. };
  2338. this.custom = function (ruleOp, field, data) {
  2339. self._append("self.p.customSortOperations." + ruleOp + ".filter.call(self,{item:this,cmName:\"" + field +
  2340. "\",iCol:self.p.iColByName[\"" + field + "\"]>=0 ? self.p.iColByName[\"" + field + "\"] : self.p.iPropByName[\"" + field +
  2341. "\"],isAddProp:self.p.iColByName[\"" + field + "\"]<0" +
  2342. ",searchValue:\"" + data + "\"})");
  2343. self._setCommand(self.custom, field);
  2344. self._resetNegate();
  2345. return self;
  2346. };
  2347. return self;
  2348. };
  2349. return new QueryObject(source, null);
  2350. },
  2351. serializeFeedback: function (callback, eventName, postData) {
  2352. var self = this, eventResult;
  2353. if (self instanceof $ && self.length > 0) {
  2354. self = self[0];
  2355. }
  2356. if (typeof postData === "string") {
  2357. return postData;
  2358. }
  2359. eventResult = $(self).triggerHandler(eventName, postData);
  2360. if (typeof eventResult === "string") {
  2361. return eventResult;
  2362. }
  2363. if (eventResult == null || typeof eventResult !== "object") {
  2364. eventResult = postData; // uses original postData
  2365. }
  2366. return $.isFunction(callback) ? callback.call(self, eventResult) : eventResult;
  2367. },
  2368. fullBoolFeedback: function (callback, eventName) {
  2369. var self = this, args = $.makeArray(arguments).slice(2), result = $(self).triggerHandler(eventName, args);
  2370. result = (result === false || result === "stop") ? false : true;
  2371. if ($.isFunction(callback)) {
  2372. var callbackResult = callback.apply(self, args);
  2373. if (callbackResult === false || callbackResult === "stop") {
  2374. result = false;
  2375. }
  2376. }
  2377. return result;
  2378. },
  2379. feedback: function (p, eventPrefix, callbackSuffix, callbackName) {
  2380. var self = this;
  2381. if (self instanceof $ && self.length > 0) {
  2382. self = self[0];
  2383. }
  2384. if (p == null || typeof callbackName !== "string" || callbackName.length < 2) {
  2385. return null; // incorrect call
  2386. }
  2387. // onSortCol -> jqGridSortCol, onSelectAll -> jqGridSelectAll, ondblClickRow -> jqGridDblClickRow
  2388. // resizeStop -> jqGridResizeStop
  2389. var eventName = callbackName.substring(0, 2) === "on" ?
  2390. "jqGrid" + eventPrefix + callbackName.charAt(2).toUpperCase() + callbackName.substring(3) :
  2391. "jqGrid" + eventPrefix + callbackName.charAt(0).toUpperCase() + callbackName.substring(1),
  2392. args = $.makeArray(arguments).slice(4),
  2393. callback = p[callbackName + callbackSuffix];
  2394. args.unshift(eventName);
  2395. args.unshift(callback);
  2396. return jgrid.fullBoolFeedback.apply(self, args);
  2397. },
  2398. builderSortIcons: function (iCol) {
  2399. // iCol is unused currently, but one can modify the code to set for example different sorting
  2400. // icons for columns based on sorttype option of colModel
  2401. var ts = this, p = ts.p, $self = $(ts),
  2402. disabledStateClasses = $self.jqGrid("getGuiStyles", "states.disabled"),
  2403. getClasses = function (ascOrDesc) {
  2404. var cm = p.colModel[iCol],
  2405. sortIconFunc = cm != null && $.isFunction(cm.sortIconName) ?
  2406. cm.sortIconName :
  2407. p.sortIconName;
  2408. var sortIconName = $.isFunction(sortIconFunc) ?
  2409. sortIconFunc.call(ts, {
  2410. order: ascOrDesc,
  2411. iCol: iCol,
  2412. cm: cm
  2413. }) :
  2414. $self.jqGrid("getIconRes", "sort." + ascOrDesc);
  2415. return jgrid.mergeCssClasses(
  2416. "ui-grid-ico-sort",
  2417. "ui-icon-" + ascOrDesc,
  2418. p.viewsortcols[1] === "horizontal" ? "ui-i-" + ascOrDesc : "",
  2419. disabledStateClasses,
  2420. sortIconName,
  2421. "ui-sort-" + p.direction
  2422. );
  2423. };
  2424. return "<span class='s-ico" + (p.sortIconsBeforeText ? " jqgrid-icons-first" : "") +
  2425. "' style='display:none'><span class='" + getClasses("asc") +
  2426. "'></span><span class='" + getClasses("desc") + "'></span></span>";
  2427. },
  2428. /**
  2429. * @param {String} id
  2430. * @param {String} text
  2431. * @param {String} icon
  2432. * @param {String} iconOnLeftOrRight - string "left", "right" or undefined
  2433. * @param {String} conner - string "left", "right" or undefined.
  2434. */
  2435. builderFmButon: function (id, text, icon, iconOnLeftOrRight, conner) {
  2436. var p = this.p, $self = $(this),
  2437. getDialogGuiStyles = function (name) {
  2438. return $self.jqGrid("getGuiStyles", "dialog." + name);
  2439. };
  2440. if (p == null) { return ""; }
  2441. return "<a id='" + id + "' class='" +
  2442. jgrid.mergeCssClasses("fm-button",
  2443. getDialogGuiStyles("fmButton"),
  2444. getDialogGuiStyles(conner === "right" ? "rightCorner" : (conner === "left" ? "leftCorner" : "defaultCorner")),
  2445. iconOnLeftOrRight === "right" ?
  2446. "fm-button-icon-right" :
  2447. (iconOnLeftOrRight === "left" ? "fm-button-icon-left" : "")
  2448. ) + "' role='button' tabindex='0'>" +
  2449. (icon ? "<span class='fm-button-icon " + ($self.jqGrid("getIconRes", icon) || icon) + "'></span>" : "") +
  2450. (text ? "<span class='fm-button-text'>" + text + "</span>" : "") +
  2451. "</a>";
  2452. },
  2453. convertOnSaveLocally: function (nData, cm, oData, id, item, iCol) {
  2454. var self = this, p = self.p;
  2455. if (p == null) {
  2456. return nData;
  2457. }
  2458. if ($.isFunction(cm.convertOnSave)) {
  2459. return cm.convertOnSave.call(this, { newValue: nData, cm: cm, oldValue: oData, id: id, item: item, iCol: iCol });
  2460. }
  2461. if (typeof oData !== "boolean" && typeof oData !== "number") {
  2462. // we support first of all editing of boolean and numeric data
  2463. // TODO: more data types (like Date) need be implemented
  2464. return nData;
  2465. }
  2466. if (typeof oData === "boolean" && (cm.edittype === "checkbox" || cm.formatter === "checkbox")) {
  2467. // convert nData to boolean if possible
  2468. var lnData = String(nData).toLowerCase(),
  2469. cbv = cm.editoptions != null && typeof cm.editoptions.value === "string" ?
  2470. cm.editoptions.value.split(":") : ["yes", "no"];
  2471. if ($.inArray(lnData, ["1", "true", cbv[0].toLowerCase()]) >= 0) {
  2472. nData = true;
  2473. } else if ($.inArray(lnData, ["0", "false", cbv[1].toLowerCase()]) >= 0) {
  2474. nData = false;
  2475. }
  2476. } else if (typeof oData === "number" && !isNaN(nData)) {
  2477. if (cm.formatter === "number" || cm.formatter === "currency") {
  2478. nData = parseFloat(nData);
  2479. } else if (cm.formatter === "integer") {
  2480. nData = parseInt(nData, 10);
  2481. }
  2482. }
  2483. return nData;
  2484. },
  2485. parseDataToHtml: function (len, ids, items, cellsToDisplay, rcnt, adjust, readAllInputData) {
  2486. var self = this, p = self.p, $self = $(self), i, j, altr, cn1, selr, idr, rd, cells, iStartTrTag,
  2487. selected = false, rowData = [], grpdata = [],
  2488. cn = (p.altRows === true && !$self.jqGrid("isBootstrapGuiStyle")) ? p.altclass : "",
  2489. grp = p.groupingView,
  2490. hiderow = false,
  2491. rn = parseInt(p.rowNum, 10), cmName, $j = $.fn.jqGrid,
  2492. // prepare to build the map rowIndexes, which will simplify us to get rowIndex
  2493. // of any row of table by its rowid.
  2494. // ??? probably rcnt can be used too
  2495. rowIndex = p.treeGrid === true && p.treeANode > -1 ?
  2496. self.rows[p.treeANode].rowIndex + 1 :
  2497. self.rows.length,
  2498. formatCol = self.formatCol,
  2499. addCell = function (rowId, cell, pos, irow, srvr, rdata) {
  2500. var v = self.formatter(rowId, cell, pos, srvr, "add", rdata);
  2501. return "<td role='gridcell' " + formatCol(pos, irow, v, srvr, rowId, rdata) + ">" + v + "</td>";
  2502. },
  2503. addMulti = function (rowid, pos, irow, checked, item) {
  2504. var checkboxHtml = "&nbsp;", hasCbox = true,
  2505. callbackParams = { rowid: rowid, iRow: irow, iCol: pos, data: item, checked: checked };
  2506. if ($.isFunction(p.hasMultiselectCheckBox)) {
  2507. hasCbox = p.hasMultiselectCheckBox.call(self, callbackParams);
  2508. }
  2509. if (hasCbox) {
  2510. checkboxHtml = $.isFunction(p.checkboxHtml) ?
  2511. p.checkboxHtml.call(self, callbackParams) :
  2512. "<input type='checkbox' id='jqg_" + p.id + "_" + rowid +
  2513. "' class='cbox' name='jqg_" + p.id + "_" + rowid + "'" +
  2514. (checked ? " checked='checked' aria-checked='true'" : " aria-checked='false'") + "/>";
  2515. }
  2516. return "<td role='gridcell' " + formatCol(pos, irow, "", null, rowid, true) + ">" +
  2517. checkboxHtml + "</td>";
  2518. },
  2519. addRowNum = function (pos, irow, pG, rN) {
  2520. var v = (parseInt(pG, 10) - 1) * parseInt(rN, 10) + 1 + irow;
  2521. return "<td role='gridcell' class='" + $j.getGuiStyles.call($self, "rowNum", "jqgrid-rownum") + "' " +
  2522. formatCol(pos, irow, v, null, irow, true) + ">" + v + "</td>";
  2523. };
  2524. if (rowIndex <= 1) { p.rowIndexes = {}; }
  2525. if ((p.datatype === "local" && !p.deselectAfterSort) || p.multiPageSelection) { selected = true; }
  2526. if (adjust) { rn *= adjust + 1; }
  2527. for (i = 0; i < Math.min(len, rn); i++) {
  2528. idr = ids[i];
  2529. rd = items[i];
  2530. cells = cellsToDisplay != null ? cellsToDisplay[i] : rd;
  2531. altr = rcnt === 1 ? 0 : rcnt; // probably rowIndex should be used instead
  2532. cn1 = (altr + i) % 2 === 1 ? cn : "";
  2533. if (selected) {
  2534. if (p.multiselect) {
  2535. selr = ($.inArray(idr, p.selarrrow) !== -1);
  2536. if (selr && p.selrow === null) { p.selrow = idr; }
  2537. } else {
  2538. selr = (idr === p.selrow);
  2539. }
  2540. } else {
  2541. selr = false;
  2542. }
  2543. iStartTrTag = rowData.length;
  2544. rowData.push(""); // it will be replaced. See rowData[iStartTrTag] below
  2545. for (j = 0; j < p.colModel.length; j++) {
  2546. cmName = p.colModel[j].name;
  2547. switch (cmName) {
  2548. case "rn":
  2549. rowData.push(addRowNum(j, i, p.page, p.rowNum));
  2550. break;
  2551. case "cb":
  2552. rowData.push(addMulti(idr, j, i, selr, rd));
  2553. break;
  2554. case "subgrid":
  2555. rowData.push($j.addSubGridCell.call($self, j, i + rcnt, idr, rd));
  2556. break;
  2557. default:
  2558. rowData.push(addCell(idr, rd[cmName], j, i + rcnt, cells, rd));
  2559. }
  2560. }
  2561. if (p.grouping) {
  2562. if ($j.groupingPrepare && !grp._locgr) {
  2563. $j.groupingPrepare.call($self, rd, i);
  2564. }
  2565. hiderow = $.isFunction(grp.groupCollapse) ?
  2566. grp.groupCollapse.call(self, {
  2567. group: grp.groups[grp.groups.length - 1],
  2568. rowid: idr,
  2569. data: rd
  2570. }) :
  2571. grp.groupCollapse;
  2572. }
  2573. rowData[iStartTrTag] = self.constructTr(idr, hiderow, cn1, rd, cells, selr);
  2574. rowData.push("</tr>");
  2575. p.rowIndexes[idr] = rowIndex;
  2576. rowIndex++;
  2577. //TODO: fix p.rowIndexes in case of usage grouping.
  2578. if (p.grouping) {
  2579. // we save the rowData in the array grpdata first.
  2580. // grpdata will collect HTML fragments of all rows of data
  2581. // of the current group. Later we call groupingRender, which
  2582. // will insert additional grouping row and concatinate all
  2583. // the HTML fragments of all rows of the group.
  2584. grpdata.push(rowData);
  2585. rowData = []; // the data for rendering are moved in grpdata
  2586. }
  2587. if (rowData.length > p.maxItemsToJoin) {
  2588. rowData = [rowData.join("")];
  2589. }
  2590. }
  2591. if (p.grouping && $j.groupingRender) {
  2592. if (readAllInputData) {
  2593. grp._locgr = true;
  2594. }
  2595. rowData = [$j.groupingRender.call($self, grpdata, rn)];
  2596. jgrid.clearArray(grpdata); //grpdata = null;
  2597. }
  2598. return rowData;
  2599. },
  2600. fillSelectOptions: function (elem, value, sep, delim, isMultiple, valuesToSelect) {
  2601. var i, so, sv, ov, optionInfo, optionInfos = [], isSelected, key, ovm,
  2602. isNoFilterValueExist = false,
  2603. mapFunc = function (n, ii) { if (ii > 0) { return n; } };
  2604. if (!value) { return; }
  2605. if (typeof value === "function") {
  2606. value = value();
  2607. }
  2608. if (typeof value === "string") {
  2609. so = value.split(delim);
  2610. for (i = 0; i < so.length; i++) {
  2611. sv = so[i].split(sep);
  2612. if (sv.length > 2) {
  2613. sv[1] = $.map(sv, mapFunc).join(sep);
  2614. }
  2615. optionInfos.push({
  2616. value: sv[0],
  2617. innerHtml: sv[1],
  2618. selectValue: $.trim(sv[0]),
  2619. selectText: $.trim(sv[1]),
  2620. selected: false
  2621. });
  2622. if (sv[0] === "") {
  2623. isNoFilterValueExist = true;
  2624. }
  2625. }
  2626. } else if (typeof value === "object") {
  2627. for (key in value) {
  2628. if (value.hasOwnProperty(key)) {
  2629. optionInfos.push({
  2630. value: key,
  2631. innerHtml: value[key],
  2632. selectValue: $.trim(key),
  2633. selectText: $.trim(value[key]),
  2634. selected: false
  2635. });
  2636. }
  2637. if (key === "") {
  2638. isNoFilterValueExist = true;
  2639. }
  2640. }
  2641. }
  2642. if (typeof valuesToSelect === "string") {
  2643. ovm = isMultiple ?
  2644. $.map(valuesToSelect.split(","), function (n) { return $.trim(n); }) :
  2645. [$.trim(valuesToSelect)];
  2646. valuesToSelect = $.trim(valuesToSelect);
  2647. // mark selection
  2648. // 1) first by value
  2649. for (i = 0; i < optionInfos.length; i++) {
  2650. optionInfo = optionInfos[i];
  2651. if (!isMultiple && optionInfo.selectValue === valuesToSelect) {
  2652. optionInfo.selected = true;
  2653. isSelected = true;
  2654. }
  2655. if (isMultiple && $.inArray(optionInfo.selectValue, ovm) > -1) {
  2656. optionInfo.selected = true;
  2657. isSelected = true;
  2658. }
  2659. }
  2660. // 2) when no selection by value, then by text
  2661. if (!isSelected) {
  2662. for (i = 0; i < optionInfos.length; i++) {
  2663. optionInfo = optionInfos[i];
  2664. if (!isMultiple && optionInfo.selectText === valuesToSelect) {
  2665. optionInfo.selected = true;
  2666. }
  2667. if (isMultiple && $.inArray(optionInfo.selectText, ovm) > -1) {
  2668. optionInfo.selected = true;
  2669. }
  2670. }
  2671. }
  2672. }
  2673. for (i = 0; i < optionInfos.length; i++) {
  2674. optionInfo = optionInfos[i];
  2675. ov = document.createElement("option");
  2676. ov.value = optionInfo.value;
  2677. ov.innerHTML = optionInfo.innerHtml;
  2678. if (optionInfo.selected) {
  2679. ov.selected = true;
  2680. }
  2681. elem.appendChild(ov);
  2682. }
  2683. return isNoFilterValueExist;
  2684. },
  2685. getMethod: function (name) {
  2686. // this should be $.jgrid object
  2687. return this.getAccessor($.fn.jqGrid, name);
  2688. },
  2689. extend: function (methods) {
  2690. $.extend($.fn.jqGrid, methods);
  2691. if (!this.no_legacy_api) {
  2692. $.fn.extend(methods);
  2693. }
  2694. }
  2695. });
  2696. var clearArray = jgrid.clearArray, jqID = jgrid.jqID,
  2697. getGridComponentIdSelector = jgrid.getGridComponentIdSelector, getGridComponentId = jgrid.getGridComponentId,
  2698. getGridComponent = jgrid.getGridComponent, stripPref = jgrid.stripPref, randId = jgrid.randId,
  2699. getAccessor = jgrid.getAccessor, convertOnSaveLocally = jgrid.convertOnSaveLocally,
  2700. stripHtml = jgrid.stripHtml, htmlEncode = jgrid.htmlEncode, htmlDecode = jgrid.htmlDecode,
  2701. mergeCssClasses = jgrid.mergeCssClasses, hasOneFromClasses = jgrid.hasOneFromClasses,
  2702. feedback = function () {
  2703. // short form of $.jgrid.feedback to save usage this.p as the first parameter
  2704. var args = $.makeArray(arguments);
  2705. args.unshift("");
  2706. args.unshift("");
  2707. args.unshift(this.p);
  2708. return jgrid.feedback.apply(this, args);
  2709. };
  2710. /**
  2711. * @param {(string|Object)} pin
  2712. */
  2713. $.fn.jqGrid = function (pin) {
  2714. var $j = $.fn.jqGrid, fn;
  2715. if (typeof pin === "string") {
  2716. fn = $j[pin];
  2717. if (!fn) {
  2718. throw ("jqGrid - No such method: " + pin);
  2719. }
  2720. return fn.apply(this, $.makeArray(arguments).slice(1));
  2721. }
  2722. return this.each(function () {
  2723. if (this.grid) { return; }
  2724. // TODO: verify that pin.locale exists in locales. If it's not exist then change it to
  2725. // en-US or some other which exist
  2726. var ts = this, localData, localDataStr, $self0 = $(ts),
  2727. isFunction = $.isFunction, isArray = $.isArray, extend = $.extend, inArray = $.inArray,
  2728. trim = $.trim, each = $.each, setSelection = $j.setSelection, getGridRes = $j.getGridRes,
  2729. fatalErrorFunction = isFunction(defaults.fatalError) ? defaults.fatalError : alert,
  2730. locale = pin.locale || defaults.locale || "en-US",
  2731. direction = locales[locale] != null && typeof locales[locale].isRTL === "boolean" ? (locales[locale].isRTL ? "rtl" : "ltr") : "ltr",
  2732. iconSet = pin.iconSet || defaults.iconSet || ((pin.guiStyle || defaults.guiStyle) === "bootstrap" || (pin.guiStyle || defaults.guiStyle) === "bootstrapPrimary" ? "glyph" : "jQueryUI"),
  2733. guiStyle = pin.guiStyle || defaults.guiStyle || "jQueryUI",
  2734. getIcon = function (path) {
  2735. //return jgrid.getIconRes(iconSet, path);
  2736. return $j.getIconRes.call(ts, path);
  2737. },
  2738. getGuiStyles = function (path, jqClasses) {
  2739. return $self0.jqGrid("getGuiStyles", path, jqClasses);
  2740. },
  2741. stdLoadError = function (jqXHR, textStatus, errorThrown) {
  2742. if (textStatus !== "abort" && errorThrown !== "abort") {
  2743. var contentType = jqXHR.getResponseHeader ("Content-Type"),
  2744. message = jqXHR.responseText || "",
  2745. processHtmlError = function (msg) {
  2746. var div = document.createElement("div"), scripts, i, bodyMatch;
  2747. // get body only and strip all scripts
  2748. bodyMatch = /<body[^>]*>([\s\S]*)<\/body\s*>/gim.exec(msg);
  2749. div.innerHTML = bodyMatch != null && bodyMatch.length === 2 ?
  2750. bodyMatch[1] : msg;
  2751. scripts = div.getElementsByTagName("script");
  2752. i = scripts.length;
  2753. while (i--) {
  2754. scripts[i].parentNode.removeChild(scripts[i]);
  2755. }
  2756. // strip html headers and get the body only
  2757. msg = div.innerHTML;
  2758. try {
  2759. // remove HTML, if it has no text
  2760. if ($.trim($(msg).text()) === "") {
  2761. msg = "";
  2762. }
  2763. }
  2764. catch (ignore) {}
  2765. return msg;
  2766. },
  2767. processJsonError = function (msg) {
  2768. try {
  2769. var errorInfo = $.parseJSON(msg), errorMessages = [], errorProp;
  2770. for (errorProp in errorInfo) {
  2771. if (errorInfo.hasOwnProperty(errorProp) && errorProp !== "StackTrace") {
  2772. errorMessages.push(errorProp + ": " + errorInfo[errorProp]);
  2773. }
  2774. }
  2775. msg = errorMessages.join("<br />");
  2776. }
  2777. catch (ignore) {}
  2778. return msg;
  2779. };
  2780. if (contentType === "text/html") {
  2781. message = processHtmlError(message);
  2782. } else if (contentType === "application/json") {
  2783. message = processJsonError(message);
  2784. } else if (contentType === "text/plain") {
  2785. // try to process as JSON
  2786. message = processJsonError(message);
  2787. }
  2788. if (jqXHR.status !== 500 && jqXHR.status !== 0) {
  2789. // add the header
  2790. message = (textStatus || errorThrown) +
  2791. (errorThrown && (errorThrown !== textStatus) ? ": " + errorThrown : "") +
  2792. " " + jqXHR.status + " " + jqXHR.statusText +
  2793. (message !== "" ? "<hr />" : "") +
  2794. message;
  2795. }
  2796. $self0.jqGrid("displayErrorMessage", message || textStatus || errorThrown);
  2797. }
  2798. };
  2799. if (pin == null) {
  2800. pin = { datatype: "local" };
  2801. }
  2802. if (pin.datastr !== undefined && isArray(pin.datastr)) {
  2803. localDataStr = pin.datastr;
  2804. pin.datastr = []; // don't clear the array, just change the value of datastr property
  2805. }
  2806. if (pin.data !== undefined) {
  2807. localData = pin.data;
  2808. pin.data = []; // don't clear the array, just change the value of data property
  2809. }
  2810. if (jgrid.formatter == null || jgrid.formatter.unused == null) {
  2811. // detect old locale file grid.locale-XX.js are included (without DEEP extend).
  2812. fatalErrorFunction("CRITICAL ERROR!!!\n\n\nOne uses probably\n\n\t$.extend($.jgrid.defaults, {...});\n\nto set default settings of jqGrid instead of the usage the DEEP version of jQuery.extend (with true as the first parameter):\n\n\t$.extend(true, $.jgrid.defaults, {...});\n\nOne other possible reason:\n\nyou included some OLD version of language file (grid.locale-en.js for example) AFTER jquery.jqGrid.min.js. For example all language files of jqGrid 4.7.0 uses non-deep call of jQuery.extend.\n\n\nSome options of jqGrid could still work, but another one will be broken.");
  2813. }
  2814. if (pin.datatype === undefined && pin.dataType !== undefined) {
  2815. // fix the bug in the usage of dataType instead of datatype
  2816. pin.datatype = pin.dataType;
  2817. delete pin.dataType;
  2818. }
  2819. if (pin.mtype === undefined && pin.type !== undefined) {
  2820. // fix the bug in the usage of type instead of mtype
  2821. pin.mtype = pin.type;
  2822. delete pin.type;
  2823. }
  2824. ts.p = { iconSet: iconSet }; // minimal initializing to get icons with respect of getIconRes method
  2825. var p = extend(true,
  2826. {
  2827. //url: "",
  2828. height: "auto",
  2829. page: 1,
  2830. rowNum: 20,
  2831. maxRowNum: 10000,
  2832. pagingDuringEditing: "prevent", // "prevent", "cancel" or "save"
  2833. sortingDuringEditing: "prevent", // "prevent", "cancel" or "save"
  2834. reloadingDuringEditing: "prevent", // "prevent", "cancel" or "save"
  2835. autoresizeOnLoad: false,
  2836. columnsToReResizing: [],
  2837. autoResizing: {
  2838. wrapperClassName: "ui-jqgrid-cell-wrapper",
  2839. //widthOfVisiblePartOfSortIcon: pin.iconSet === "fontAwesome" ? 13 : 12,
  2840. minColWidth: 33,
  2841. maxColWidth: 300,
  2842. adjustGridWidth: true, // shrinkToFit and widthOrg (no width option or width:"auto" during jqGrid creation will be detected) will be used additionally with adjustGridWidth
  2843. compact: false,
  2844. fixWidthOnShrink: false
  2845. },
  2846. doubleClickSensitivity: 250,
  2847. minResizingWidth: 10,
  2848. rowTotal: null,
  2849. records: 0,
  2850. pager: "",
  2851. pgbuttons: true,
  2852. pginput: true,
  2853. colModel: [],
  2854. additionalProperties: [],
  2855. arrayReader: [],
  2856. rowList: [],
  2857. colNames: [],
  2858. sortorder: "asc",
  2859. threeStateSort: false,
  2860. //showOneSortIcon: pin.showOneSortIcon !== undefined ? pin.showOneSortIcon :
  2861. // pin.iconSet === "fontAwesome" ? true : false, // hide or set ui-state-disabled class on the other icon
  2862. sortname: "",
  2863. //datatype: pin.datatype !== undefined ? pin.datatype : // datatype parameter are specified - use it
  2864. // localData !== undefined || pin.url == null ? "local" : // data parameter specified or no url are specified
  2865. // pin.jsonReader != null && typeof pin.jsonReader === "object" ? "json" : "xml", // if jsonReader are specified - use "json". In all other cases - use "xml"
  2866. mtype: "GET",
  2867. altRows: false,
  2868. selarrrow: [],
  2869. savedRow: [],
  2870. editingInfo: {},
  2871. shrinkToFit: true,
  2872. xmlReader: {},
  2873. //jsonReader: {},
  2874. subGrid: false,
  2875. subGridModel: [],
  2876. reccount: 0,
  2877. lastpage: 0,
  2878. lastsort: 0,
  2879. selrow: null,
  2880. singleSelectClickMode: "toggle",
  2881. selectOnContextMenu: true,
  2882. beforeSelectRow: null,
  2883. onSelectRow: null,
  2884. onSortCol: null,
  2885. ondblClickRow: null,
  2886. onRightClickRow: null,
  2887. onPaging: null,
  2888. onSelectAll: null,
  2889. onInitGrid: null,
  2890. loadComplete: null,
  2891. gridComplete: null,
  2892. loadError: stdLoadError,
  2893. loadBeforeSend: null,
  2894. afterInsertRow: null,
  2895. beforeRequest: null,
  2896. beforeProcessing: null,
  2897. onHeaderClick: null,
  2898. viewrecords: false,
  2899. loadonce: false,
  2900. forceClientSorting: false,
  2901. multiselect: false,
  2902. multikey: false,
  2903. editurl: "clientArray",
  2904. search: false,
  2905. caption: "",
  2906. hidegrid: true,
  2907. hiddengrid: false,
  2908. useUnformattedDataForCellAttr: true,
  2909. postData: {},
  2910. userData: {},
  2911. treeGrid: false,
  2912. treeGridModel: "nested",
  2913. treeReader: {},
  2914. treeANode: -1,
  2915. ExpandColumn: null,
  2916. tree_root_level: 0,
  2917. prmNames: {
  2918. page: "page",
  2919. rows: "rows",
  2920. sort: "sidx",
  2921. order: "sord",
  2922. search: "_search",
  2923. filters: "filters",
  2924. nd: "nd",
  2925. id: "id",
  2926. idold: "idOld",
  2927. oper: "oper",
  2928. editoper: "edit",
  2929. addoper: "add",
  2930. deloper: "del",
  2931. subgridid: "id",
  2932. npage: null,
  2933. totalrows: "totalrows"
  2934. },
  2935. forceFit: false,
  2936. gridstate: "visible",
  2937. cellEdit: false,
  2938. iCol: -1,
  2939. iRow: -1,
  2940. //cellsubmit: pin.cellurl === undefined ? "clientArray" : "remote",
  2941. nv: 0,
  2942. loadui: "enable",
  2943. toolbar: [false, ""],
  2944. scroll: false,
  2945. multiboxonly: false,
  2946. deselectAfterSort: true,
  2947. resetPageAfterSort: true,
  2948. multiPageSelection: false,
  2949. selectAllMode: "filtered",
  2950. scrollrows: false,
  2951. autowidth: false,
  2952. scrollOffset: 18,
  2953. cellLayout: 5,
  2954. subGridWidth: 16,
  2955. multiselectWidth: 16,
  2956. multiselectPosition: "left",
  2957. gridview: true,
  2958. rownumWidth: 25,
  2959. rownumbers: false,
  2960. pagerpos: "center",
  2961. footerrow: false,
  2962. userDataOnFooter: false,
  2963. hoverrows: true,
  2964. altclass: "ui-priority-secondary",
  2965. viewsortcols: [false, "vertical", true],
  2966. resizeclass: "",
  2967. autoencode: true, // one can use false to have better backwards compatibility, but one have to prevent Cross Site Scripting (XSS) manually
  2968. autoEncodeOnEdit: false,
  2969. remapColumns: [],
  2970. cmNamesInputOrder: [],
  2971. ajaxGridOptions: {},
  2972. direction: direction,
  2973. toppager: false,
  2974. headertitles: false,
  2975. scrollTimeout: 40,
  2976. maxItemsToJoin: 32768,
  2977. data: [],
  2978. lastSelectedData: [],
  2979. quickEmpty: "quickest", // false, true or "quickest"
  2980. /** @dict */
  2981. _index: {},
  2982. indexByColumnData: {},
  2983. dataIndexById: {},
  2984. iColByName: {},
  2985. iPropByName: {},
  2986. reservedColumnNames: ["rn", "cb", "subgrid"],
  2987. grouping: false,
  2988. groupingView: {
  2989. groupField: [],
  2990. groupOrder: [],
  2991. groupText: [],
  2992. groupColumnShow: [],
  2993. groupSummary: [],
  2994. showSummaryOnHide: false,
  2995. useDefaultValuesOnGrouping: true,
  2996. summary: [],
  2997. displayField: [],
  2998. groupSummaryPos: [],
  2999. formatDisplayField: [],
  3000. _locgr: false,
  3001. commonIconClass: getIcon("grouping.common"),
  3002. plusicon: getIcon("grouping.plus"),
  3003. minusicon: getIcon("grouping.minus")
  3004. },
  3005. ignoreCase: true,
  3006. cmTemplate: {},
  3007. idPrefix: "",
  3008. iconSet: iconSet, // "fontAwesome" or "jQueryUI" or some custom value
  3009. guiStyle: guiStyle,
  3010. locale: locale,
  3011. multiSort: false,
  3012. showSortOrder: true,
  3013. sortOrderPosition: "afterSortIcons", // "afterSortIcons", "beforeSortIcons"
  3014. multiSortOrder: "lastClickedFirstSorted", // "lastClickedLastSorted", "lastClickedFirstSorted" or callback reodering function
  3015. maxSortColumns: 3,
  3016. treeIcons: {
  3017. commonIconClass: getIcon("treeGrid.common"),
  3018. plusLtr: getIcon("treeGrid.plusLtr"),
  3019. plusRtl: getIcon("treeGrid.plusRtl"),
  3020. minus: getIcon("treeGrid.minus"),
  3021. leaf: getIcon("treeGrid.leaf")
  3022. }
  3023. },
  3024. //locales[locale].defaults,
  3025. defaults,
  3026. {
  3027. navOptions: extend(true, {
  3028. commonIconClass: getIcon("nav.common"),
  3029. editicon: getIcon("nav.edit"),
  3030. addicon: getIcon("nav.add"),
  3031. delicon: getIcon("nav.del"),
  3032. searchicon: getIcon("nav.search"),
  3033. refreshicon: getIcon("nav.refresh"),
  3034. viewicon: getIcon("nav.view"),
  3035. saveicon: getIcon("nav.save"),
  3036. cancelicon: getIcon("nav.cancel"),
  3037. buttonicon: getIcon("nav.newbutton")
  3038. }, jgrid.nav || {}),
  3039. actionsNavOptions: extend(true, {
  3040. commonIconClass: getIcon("actions.common"),
  3041. editicon: getIcon("actions.edit"),
  3042. delicon: getIcon("actions.del"),
  3043. saveicon: getIcon("actions.save"),
  3044. cancelicon: getIcon("actions.cancel")
  3045. }, jgrid.actionsNav || {}),
  3046. formEditing: extend(true, {
  3047. commonIconClass: getIcon("form.common"),
  3048. prevIcon: getIcon("form.prev"),
  3049. nextIcon: getIcon("form.next"),
  3050. saveicon: [true, "left", getIcon("form.save")],
  3051. closeicon: [true, "left", getIcon("form.undo")]
  3052. }, jgrid.edit || {}),
  3053. searching: extend(true, {
  3054. commonIconClass: getIcon("search.common"),
  3055. findDialogIcon: getIcon("search.search"),
  3056. resetDialogIcon: getIcon("search.reset"),
  3057. queryDialogIcon: getIcon("search.query")
  3058. }, jgrid.search || {}),
  3059. formViewing: extend(true, {
  3060. commonIconClass: getIcon("form.common"),
  3061. prevIcon: getIcon("form.prev"),
  3062. nextIcon: getIcon("form.next"),
  3063. closeicon: [true, "left", getIcon("form.cancel")]
  3064. }, jgrid.view || {}),
  3065. formDeleting: extend(true, {
  3066. commonIconClass: getIcon("form.common"),
  3067. delicon: [true, "left", getIcon("form.del")],
  3068. cancelicon: [true, "left", getIcon("form.cancel")]
  3069. }, jgrid.del || {})
  3070. },
  3071. pin || {}),
  3072. getRes = function (path) {
  3073. return getGridRes.call($self0, path);
  3074. },
  3075. getDef = function (path) {
  3076. var gridParam = jgrid.getRes(p, path);
  3077. return gridParam !== undefined ? gridParam : getGridRes.call($self0, "defaults." + path);
  3078. };
  3079. // set dynamic options
  3080. p.recordpos = p.recordpos || (p.direction === "rtl" ? "left" : "right");
  3081. p.autoResizing.widthOfVisiblePartOfSortIcon =
  3082. p.autoResizing.widthOfVisiblePartOfSortIcon !== undefined ?
  3083. p.autoResizing.widthOfVisiblePartOfSortIcon :
  3084. (p.iconSet === "fontAwesome" ? 13 : 12);
  3085. //p.showOneSortIcon = p.showOneSortIcon !== undefined ? p.showOneSortIcon :
  3086. // (p.iconSet === "fontAwesome" ? true : false);
  3087. p.datatype = p.datatype !== undefined ? p.datatype : // datatype parameter are specified - use it
  3088. localData !== undefined || p.url == null ? "local" : // data parameter specified or no url are specified
  3089. p.jsonReader != null && typeof p.jsonReader === "object" ? "json" : "xml"; // if jsonReader are specified - use "json". In all other cases - use "xml"
  3090. p.jsonReader = p.jsonReader || {};
  3091. p.url = p.url || "";
  3092. p.cellsubmit = p.cellsubmit !== undefined ? p.cellsubmit :
  3093. p.cellurl === undefined ? "clientArray" : "remote";
  3094. p.gridview = p.gridview !== undefined ? p.gridview : (p.afterInsertRow == null);
  3095. if (localData !== undefined) {
  3096. p.data = localData;
  3097. pin.data = localData;
  3098. }
  3099. if (localDataStr !== undefined) {
  3100. p.datastr = localDataStr;
  3101. pin.datastr = localDataStr;
  3102. }
  3103. if (ts.tagName.toUpperCase() !== "TABLE") {
  3104. fatalErrorFunction("Element is not a table!");
  3105. return;
  3106. }
  3107. if (ts.id === "") {
  3108. $self0.attr("id", randId());
  3109. }
  3110. if (document.documentMode !== undefined) { // IE only
  3111. if (document.documentMode <= 5) {
  3112. fatalErrorFunction("Grid can not be used in this ('quirks') mode!");
  3113. return;
  3114. }
  3115. }
  3116. $self0.empty().attr("tabindex", "0");
  3117. ts.p = p;
  3118. p.id = ts.id;
  3119. p.idSel = "#" + jqID(ts.id);
  3120. p.gBoxId = getGridComponentId.call(ts, COMPONENT_NAMES.GRID_BOX_DIV); // gbox id like "gbox_list" or "gbox_my.list"
  3121. p.gBox = getGridComponentIdSelector.call(ts, COMPONENT_NAMES.GRID_BOX_DIV); // gbox selector like "#gbox_list" or "#gbox_my\\.list"
  3122. p.gViewId = getGridComponentId.call(ts, COMPONENT_NAMES.GRID_VIEW_DIV); // gview id like "gview_list" or "gview_my.list"
  3123. p.gView = getGridComponentIdSelector.call(ts, COMPONENT_NAMES.GRID_VIEW_DIV); // gview selector like "#gview_list" or "#gview_my\\.list"
  3124. p.rsId = getGridComponentId.call(ts, COMPONENT_NAMES.COLUMN_RESIZER_DIV); // vertical div inside of gbox which will be seen on resizing of columns
  3125. p.rs = getGridComponentIdSelector.call(ts, COMPONENT_NAMES.COLUMN_RESIZER_DIV); // vertical div inside of gbox which will be seen on resizing of columns
  3126. p.cbId = getGridComponentId.call(ts, COMPONENT_NAMES.HEADER_SELECT_ALL_ROWS_CHECKBOX); // "cb_" +id
  3127. p.cb = getGridComponentIdSelector.call(ts, COMPONENT_NAMES.HEADER_SELECT_ALL_ROWS_CHECKBOX); // "cb_" +id
  3128. var fixScrollOffsetAndhBoxPadding = jgrid.fixScrollOffsetAndhBoxPadding,
  3129. buildColNameMap = function (colModel) {
  3130. var m = {}, i, n = colModel.length;
  3131. for (i = 0; i < n; i++) {
  3132. m[colModel[i].name] = i;
  3133. }
  3134. return m;
  3135. },
  3136. buildEmptyIndexedColumnMap = function () {
  3137. var m = {}, i, colModel = p.colModel, n = colModel.length, cm;
  3138. for (i = 0; i < n; i++) {
  3139. cm = colModel[i];
  3140. if (cm.createColumnIndex ||
  3141. (p.createColumnIndex && cm.createColumnIndex !== false) ||
  3142. (cm.stype === "select" && (cm.searchoptions || {}).generateValue) ||
  3143. (cm.edittype === "select" && (cm.editoptions || {}).generateValue)) {
  3144. m[colModel[i].name] = {};
  3145. }
  3146. }
  3147. return m;
  3148. },
  3149. buildAddPropMap = function (additionalProperties) {
  3150. var m = {}, i, n = additionalProperties.length, addPropInfo;
  3151. for (i = 0; i < n; i++) {
  3152. addPropInfo = additionalProperties[i];
  3153. m[typeof addPropInfo === "string" ? addPropInfo : addPropInfo.name] = i;
  3154. }
  3155. return m;
  3156. },
  3157. rebuildRowIndexes = function () {
  3158. var rowIndexes = {}, row, i;
  3159. this.p.rowIndexes = rowIndexes;
  3160. for (i = 0; i < this.rows.length; i++) {
  3161. row = this.rows[i];
  3162. if ($(row).hasClass("jqgrow")) {
  3163. rowIndexes[row.id] = row.rowIndex;
  3164. }
  3165. }
  3166. },
  3167. buildArrayReader = function () {
  3168. var i, colModel = p.colModel, cmNamesInputOrder = p.cmNamesInputOrder,
  3169. additionalProperties = p.additionalProperties, n = cmNamesInputOrder.length, arrayReaderInfos,
  3170. name, index, order;
  3171. p.arrayReaderInfos = {};
  3172. arrayReaderInfos = p.arrayReaderInfos;
  3173. for (order = 0; order < n; order++) {
  3174. name = cmNamesInputOrder[order];
  3175. if (inArray(name, p.reservedColumnNames) < 0 && !arrayReaderInfos.hasOwnProperty(name)) {
  3176. index = p.iColByName[name];
  3177. if (index !== undefined) {
  3178. arrayReaderInfos[name] = { name: name, index: index, order: order, type: 0 }; // INPUT_NAME_TYPE.COL_NAME
  3179. } else {
  3180. index = p.iPropByName[name];
  3181. if (index !== undefined) {
  3182. arrayReaderInfos[name] = { name: name, index: index, order: order, type: 1 };// INPUT_NAME_TYPE.ADDITIONAL_PROPERTY
  3183. } else if (name === (p.prmNames.rowidName || "rowid")) {
  3184. arrayReaderInfos[name] = { index: index, type: 2 };// INPUT_NAME_TYPE.ROWID
  3185. }
  3186. }
  3187. }
  3188. }
  3189. n = colModel.length;
  3190. for (i = 0; i < n; i++) {
  3191. name = colModel[i].name;
  3192. if (inArray(name, p.reservedColumnNames) < 0 && !arrayReaderInfos.hasOwnProperty(name)) {
  3193. arrayReaderInfos[name] = { name: name, index: i, order: order, type: 0 };// INPUT_NAME_TYPE.COL_NAME
  3194. order++;
  3195. }
  3196. }
  3197. n = additionalProperties.length;
  3198. for (i = 0; i < n; i++) {
  3199. name = additionalProperties[i];
  3200. if (name != null && !arrayReaderInfos.hasOwnProperty(name)) {
  3201. if (typeof name === "object" && $.type(name.name) === "string") {
  3202. name = name.name;
  3203. }
  3204. arrayReaderInfos[name] = { name: name, index: i, order: order, type: 1 };
  3205. order++;
  3206. }
  3207. }
  3208. },
  3209. myResizerClickHandler = function (e) {
  3210. var pageX = $(this).data("pageX");
  3211. if (pageX) {
  3212. pageX = String(pageX).split(";");
  3213. pageX = pageX[pageX.length - 1];
  3214. $(this).data("pageX", pageX + ";" + e.pageX);
  3215. } else {
  3216. $(this).data("pageX", e.pageX);
  3217. }
  3218. },
  3219. intNum = function (val, defval) {
  3220. val = parseInt(val, 10);
  3221. if (isNaN(val)) { return defval || 0; }
  3222. return val;
  3223. },
  3224. grid = {
  3225. headers: [],
  3226. cols: [],
  3227. footers: [],
  3228. // Some properties will be created dynamically on demand
  3229. // cDiv
  3230. // uDiv
  3231. // topDiv
  3232. // hDiv
  3233. // bDiv
  3234. // sDiv
  3235. // ubDiv
  3236. // fhDiv
  3237. // fbDiv
  3238. // fsDiv
  3239. // width
  3240. // newWidth
  3241. // resizing
  3242. // scrollTop
  3243. // timer
  3244. // prevRowHeight
  3245. dragStart: function (i, x, y, $th) {
  3246. var self = this, $bDiv = $(self.bDiv), gridOffset = $bDiv.closest(p.gBox).offset(),
  3247. // it's better to use exact position of the border on the right of the current header
  3248. startX = $th.offset().left + (p.direction === "rtl" ? 0 : self.headers[i].width + (jgrid.cell_width ? 0 : intNum(p.cellLayout, 0)) - 2);
  3249. self.resizing = { idx: i, startX: startX, sOL: startX, moved: false, delta: startX - x.pageX };
  3250. self.curGbox = $(p.rs);
  3251. self.curGbox.prependTo("body"); // change the parent to be able to move over the ranges of the gBox
  3252. self.curGbox.css({ display: "block", left: startX, top: y[1] + gridOffset.top + 1, height: y[2] });
  3253. self.curGbox.css("height", (y[2] - (self.curGbox.outerHeight() - self.curGbox.height())) + "px");
  3254. self.curGbox.data("idx", i);
  3255. self.curGbox.data("delta", startX - x.pageX);
  3256. myResizerClickHandler.call(this.curGbox, x);
  3257. feedback.call(getGridComponent(COMPONENT_NAMES.BODY_TABLE, $bDiv)[0], "resizeStart", x, i);
  3258. document.onselectstart = function () { return false; };
  3259. $(document)
  3260. .on("mousemove.jqGrid", function (e) {
  3261. if (grid.resizing) {
  3262. grid.dragMove(e);
  3263. return false;
  3264. }
  3265. })
  3266. .on("mouseup.jqGrid" + p.id, function () {
  3267. if (grid.resizing) {
  3268. grid.dragEnd();
  3269. return false;
  3270. }
  3271. });
  3272. },
  3273. dragMove: function (x) {
  3274. var self = this, resizing = self.resizing;
  3275. if (resizing) {
  3276. var diff = x.pageX + resizing.delta - resizing.startX, headers = self.headers, h = headers[resizing.idx],
  3277. newWidth = p.direction === "ltr" ? h.width + diff : h.width - diff, hn, nWn,
  3278. minResizingWidth = ((p.colModel[resizing.idx] || {}).autoResizing || {}).minColWidth || p.minResizingWidth;
  3279. resizing.moved = true;
  3280. if (newWidth > minResizingWidth) {
  3281. if (self.curGbox == null) {
  3282. self.curGbox = $(p.rs);
  3283. }
  3284. self.curGbox.css({ left: resizing.sOL + diff });
  3285. if (p.forceFit === true) {
  3286. hn = headers[resizing.idx + p.nv];
  3287. nWn = p.direction === "ltr" ? hn.width - diff : hn.width + diff;
  3288. if (nWn > p.autoResizing.minColWidth) {
  3289. h.newWidth = newWidth;
  3290. hn.newWidth = nWn;
  3291. }
  3292. } else {
  3293. self.newWidth = p.direction === "ltr" ? p.tblwidth + diff : p.tblwidth - diff;
  3294. h.newWidth = newWidth;
  3295. }
  3296. }
  3297. }
  3298. },
  3299. resizeColumn: function (idx, skipCallbacks, skipGridAdjustments) {
  3300. var self = this, headers = self.headers, footers = self.footers, h = headers[idx], hn, nw = h.newWidth || h.width,
  3301. $bTable = getGridComponent(COMPONENT_NAMES.BODY_TABLE, self.bDiv), $hTable = getGridComponent(COMPONENT_NAMES.HEADER_TABLE, self.hDiv),
  3302. hCols = $hTable.children("thead").children("tr").first()[0].cells;
  3303. nw = parseInt(nw, 10);
  3304. p.colModel[idx].width = nw;
  3305. h.width = nw;
  3306. hCols[idx].style.width = nw + "px";
  3307. self.cols[idx].style.width = nw + "px";
  3308. if (self.fbRows) {
  3309. $(self.fbRows[0].cells[idx]).css("width", nw);
  3310. $(getGridComponent(COMPONENT_NAMES.FROZEN_HEADER_TABLE, self.fhDiv)[0].rows[0].cells[idx]).css("width", nw);
  3311. if (p.footerrow) {
  3312. $(getGridComponent(COMPONENT_NAMES.FROZEN_FOOTER_TABLE, self.fsDiv)[0].rows[0].cells[idx]).css("width", nw);
  3313. }
  3314. }
  3315. if (footers.length > 0) { footers[idx].style.width = nw + "px"; }
  3316. if (skipGridAdjustments !== true) {
  3317. fixScrollOffsetAndhBoxPadding.call($bTable[0]);
  3318. }
  3319. if (p.forceFit === true) {
  3320. hn = headers[idx + p.nv]; // next visible th
  3321. nw = hn.newWidth || hn.width;
  3322. hn.width = nw;
  3323. hCols[idx + p.nv].style.width = nw + "px";
  3324. self.cols[idx + p.nv].style.width = nw + "px";
  3325. if (footers.length > 0) { footers[idx + p.nv].style.width = nw + "px"; }
  3326. p.colModel[idx + p.nv].width = nw;
  3327. } else {
  3328. p.tblwidth = self.newWidth || p.tblwidth;
  3329. //$bTable.css("width", p.tblwidth + "px");
  3330. //getGridComponent(COMPONENT_NAMES.HEADER_TABLE, self.hDiv).css("width", p.tblwidth + "px");
  3331. if (skipGridAdjustments !== true) {
  3332. self.hDiv.scrollLeft = self.bDiv.scrollLeft;
  3333. if (p.footerrow) {
  3334. //getGridComponent(COMPONENT_NAMES.FOOTER_TABLE, self.sDiv).css("width", p.tblwidth + "px");
  3335. self.sDiv.scrollLeft = self.bDiv.scrollLeft;
  3336. }
  3337. }
  3338. }
  3339. if (!p.autowidth && (p.widthOrg === undefined || p.widthOrg === "auto" || p.widthOrg === "100%") && skipGridAdjustments !== true) {
  3340. $j.setGridWidth.call($bTable, self.newWidth + p.scrollOffset, false);
  3341. }
  3342. if (!skipCallbacks) {
  3343. feedback.call($bTable[0], "resizeStop", nw, idx);
  3344. }
  3345. },
  3346. dragEnd: function () {
  3347. var self = this;
  3348. self.hDiv.style.cursor = "default";
  3349. if (self.resizing) {
  3350. if (self.resizing !== null && self.resizing.moved === true) {
  3351. $(self.headers[self.resizing.idx].el).removeData("autoResized");
  3352. self.resizeColumn(self.resizing.idx, false);
  3353. }
  3354. $(p.rs).removeData("pageX");
  3355. self.resizing = false;
  3356. setTimeout(function () {
  3357. $(p.rs).css("display", "none")
  3358. .prependTo(p.gBox); // restore the parent
  3359. }, p.doubleClickSensitivity);
  3360. }
  3361. self.curGbox = null;
  3362. document.onselectstart = function () { return true; };
  3363. $(document).off("mousemove.jqGrid mouseup.jqGrid" + p.id);
  3364. },
  3365. populateVisible: function () {
  3366. var self = this, $self = $(self), gridSelf = self.grid, bDiv = gridSelf.bDiv, $bDiv = $(bDiv);
  3367. if (gridSelf.timer) { clearTimeout(gridSelf.timer); }
  3368. gridSelf.timer = null;
  3369. var dh = $bDiv.height();
  3370. if (!dh) { return; }
  3371. var firstDataRow, rh;
  3372. if (self.rows.length) {
  3373. try {
  3374. firstDataRow = self.rows[1]; // self.rows[0] is cols row (the first row (.jqgfirstrow)) used only to set column width
  3375. rh = firstDataRow ? $(firstDataRow).outerHeight() || gridSelf.prevRowHeight : gridSelf.prevRowHeight;
  3376. } catch (pv) {
  3377. rh = gridSelf.prevRowHeight;
  3378. }
  3379. }
  3380. if (!rh) { return; }
  3381. gridSelf.prevRowHeight = rh;
  3382. var rn = p.rowNum;
  3383. gridSelf.scrollTop = bDiv.scrollTop;
  3384. var scrollTop = gridSelf.scrollTop;
  3385. var ttop = Math.round($self.position().top) - scrollTop;
  3386. var tbot = ttop + $self.height();
  3387. var div = rh * rn;
  3388. var page, npage, empty;
  3389. if (tbot < dh && ttop <= 0 &&
  3390. (p.lastpage === undefined || (parseInt((tbot + scrollTop + div - 1) / div, 10) || 0) <= p.lastpage)) {
  3391. npage = parseInt((dh - tbot + div - 1) / div, 10) || 1;
  3392. if (tbot >= 0 || npage < 2 || p.scroll === true) {
  3393. page = (Math.round((tbot + scrollTop) / div) || 0) + 1;
  3394. ttop = -1;
  3395. } else {
  3396. ttop = 1;
  3397. }
  3398. }
  3399. if (ttop > 0) {
  3400. page = (parseInt(scrollTop / div, 10) || 0) + 1;
  3401. npage = (parseInt((scrollTop + dh) / div, 10) || 0) + 2 - page;
  3402. empty = true;
  3403. }
  3404. if (npage) {
  3405. if (p.lastpage && (page > p.lastpage || p.lastpage === 1 || (page === p.page && page === p.lastpage))) {
  3406. return;
  3407. }
  3408. if (gridSelf.hDiv.loading) {
  3409. gridSelf.timer = setTimeout(function () { gridSelf.populateVisible.call(self); }, p.scrollTimeout);
  3410. } else {
  3411. p.page = page;
  3412. if (empty) {
  3413. gridSelf.selectionPreserver.call(self);
  3414. gridSelf.emptyRows.call(self, false, false);
  3415. }
  3416. gridSelf.populate.call(self, npage);
  3417. }
  3418. }
  3419. },
  3420. scrollGrid: function () { // this must be bDiv
  3421. if (p.scroll) {
  3422. var scrollTop = this.scrollTop;
  3423. // save last scrollTop of bDiv as property of grid object
  3424. if (grid.scrollTop === undefined) { grid.scrollTop = 0; }
  3425. if (scrollTop !== grid.scrollTop) {
  3426. grid.scrollTop = scrollTop;
  3427. if (grid.timer) { clearTimeout(grid.timer); }
  3428. grid.timer = setTimeout(function () { grid.populateVisible.call(ts); }, p.scrollTimeout);
  3429. }
  3430. }
  3431. grid.hDiv.scrollLeft = this.scrollLeft;
  3432. if (p.footerrow) {
  3433. grid.sDiv.scrollLeft = this.scrollLeft;
  3434. }
  3435. return false;
  3436. },
  3437. selectionPreserver: function () {
  3438. var self = this, $self = $(self), sr = p.selrow, sra = p.selarrrow ? $.makeArray(p.selarrrow) : null,
  3439. bDiv = self.grid.bDiv, left = bDiv.scrollLeft,
  3440. restoreSelection = function () {
  3441. var i;
  3442. p.selrow = null;
  3443. if (!p.multiPageSelection) {
  3444. clearArray(p.selarrrow); // p.selarrrow = [];
  3445. if (p.multiselect && sra && sra.length > 0) {
  3446. for (i = 0; i < sra.length; i++) {
  3447. if (sra[i] !== sr) {
  3448. setSelection.call($self, sra[i], false, null);
  3449. }
  3450. }
  3451. }
  3452. if (sr) {
  3453. setSelection.call($self, sr, false, null);
  3454. }
  3455. }
  3456. bDiv.scrollLeft = left;
  3457. $self.off(".selectionPreserver", restoreSelection);
  3458. };
  3459. $self.on("jqGridGridComplete.selectionPreserver", restoreSelection);
  3460. }
  3461. };
  3462. ts.grid = grid;
  3463. feedback.call(ts, "beforeInitGrid");
  3464. p.iColByName = buildColNameMap(p.colModel);
  3465. p.iPropByName = buildAddPropMap(p.additionalProperties);
  3466. // TODO: replace altclass : "ui-priority-secondary",
  3467. // set default buttonicon : "ui-icon-newwin" of navButtonAdd: fa-external-link, fa-desktop or other
  3468. // change the order in $.extend to allows to set icons using $.jgrid (for example $.jgrid.nav). It will be ovewritten currently by p.navOptions which we set above.
  3469. jgrid.msie = jgrid.msiever() > 0;
  3470. var gv = $("<div class='" + getGuiStyles("gView", "ui-jqgrid-view") + "' role='grid' aria-multiselectable='" + !!p.multiselect + "'></div>"),
  3471. isMSIE = jgrid.msie, dir;
  3472. p.direction = trim(p.direction.toLowerCase());
  3473. if (inArray(p.direction, ["ltr", "rtl"]) === -1) { p.direction = "ltr"; }
  3474. dir = p.direction;
  3475. $(gv).insertBefore(ts);
  3476. $self0.removeClass("scroll").appendTo(gv);
  3477. var eg = $("<div class='" + getGuiStyles("gBox", "ui-jqgrid") + "'></div>");
  3478. $(eg).attr({ "id": p.gBoxId, "dir": dir }).insertBefore(gv);
  3479. $(gv).attr("id", p.gViewId).appendTo(eg);
  3480. $("<div class='" + getGuiStyles("overlay", "jqgrid-overlay") + "' id='lui_" + p.id + "'></div>").insertBefore(gv);
  3481. $("<div class='" + getGuiStyles("loading", "loading") + "' id='load_" + p.id + "'>" + getDef("loadtext") + "</div>").insertBefore(gv);
  3482. $self0.attr({ "role": "presentation", "aria-labelledby": "gbox_" + ts.id });
  3483. var sortkeys = ["shiftKey", "altKey", "ctrlKey"],
  3484. // for reading of array of items from the input data it's required to know the
  3485. // mapping of input items to the column names (colModel[iCol].name items).
  3486. // The function normalizeRemapColumns converts p.remapColumns to p.cmNamesInputOrder and fills
  3487. // p.cmNamesInputOrder with the names colModel items.
  3488. // The function should be called only if no p.cmNamesInputOrder is specified
  3489. normalizeRemapColumns = function () {
  3490. // offset is the number of columns in colModel which should be skipped in calculation of the mapping
  3491. // offset is the number of columns from the list "rn", "cb", "subgrid".
  3492. // The index 0 in the p.remapColumns means the first column after the "rn", "cb", "subgrid"
  3493. var remapColumns = p.remapColumns, colModel = p.colModel, nCol = colModel.length, cmNames = [], i, remappedCmNames,
  3494. name;
  3495. for (i = 0; i < nCol; i++) {
  3496. name = colModel[i].name;
  3497. if (inArray(name, p.reservedColumnNames) < 0) {
  3498. cmNames.push(name);
  3499. }
  3500. }
  3501. // it's important to remark that the numbers in remapColumns or in
  3502. // jsonReder, localReader, xmlReader are based on the position of column
  3503. // in colModel BEFORE adding columns "rn", "cb", "subgrid"
  3504. if (remapColumns != null) {
  3505. // now we should remap items in cmNames corresponds to the indexes from p.remapColumns array
  3506. remappedCmNames = cmNames.slice(); // make copy of cmNames array
  3507. for (i = 0; i < remapColumns.length; i++) {
  3508. cmNames[i] = remappedCmNames[remapColumns[i]];
  3509. }
  3510. }
  3511. p.cmNamesInputOrder = cmNames;
  3512. },
  3513. stripGridPrefix = function (rowId) {
  3514. return stripPref(p.idPrefix, rowId);
  3515. },
  3516. formatCol = function (pos, rowInd, tv, rawObject, rowId, rdata) {
  3517. var cm = p.colModel[pos], cellAttrFunc,
  3518. rPrefix = cm.autoResizable ? "<span class='" + p.autoResizing.wrapperClassName + "'>" : "",
  3519. // see https://github.com/free-jqgrid/jqGrid/issues/74#issuecomment-107675796
  3520. // we will cut formatted string like "<span class='ui-jqgrid-cell-wrapper'>193,81</span>"
  3521. // to substring "193,81". The formatting (comma, point, dollar and so on) still stay.
  3522. unwrappedCellValue = cm.autoResizable ? tv.substring(rPrefix.length, tv.length - "</span>".length) : tv,
  3523. cellValue = p.useUnformattedDataForCellAttr && rdata != null ?
  3524. rdata[cm.name] :
  3525. (cm.autoResizable ? unwrappedCellValue : tv),
  3526. result, classes = cm.classes,
  3527. styleValue = cm.align ? "text-align:" + cm.align + ";" : "",
  3528. attrStr, matches, value, tilteValue,
  3529. encodeAttr = function (v) {
  3530. return typeof v === "string" ? v.replace(/'/g, "&#39;") : v;
  3531. },
  3532. rest = " aria-describedby='" + p.id + "_" + cm.name + "'";
  3533. if (cm.hidden === true) { styleValue += "display:none;"; }
  3534. if (rowInd === 0) {
  3535. styleValue += "width: " + grid.headers[pos].width + "px;";
  3536. } else if (isFunction(cm.cellattr) || (typeof cm.cellattr === "string" && jgrid.cellattr != null && isFunction(jgrid.cellattr[cm.cellattr]))) {
  3537. cellAttrFunc = isFunction(cm.cellattr) ? cm.cellattr : jgrid.cellattr[cm.cellattr];
  3538. attrStr = cellAttrFunc.call(ts, rowId, cellValue, rawObject, cm, rdata, unwrappedCellValue);
  3539. if (typeof attrStr === "string") {
  3540. // ??? probably one can create object with properties from the attrStr
  3541. // and then to use one common function with constructTr to combine the default
  3542. // properties with the properties used in cellattr and rowattr.
  3543. // Probably one could use $.extend with the most attributes. The exception are
  3544. // only class and style attributes which hold multi-values with " " or ";" as separator
  3545. attrStr = attrStr.replace(/\n/g, "&#xA;");
  3546. while (true) {
  3547. // we have to use ? in the construction ([^\2]*?) to have non-greedy (lazy, minimal) matching
  3548. // so that we will find the FIRST closing quote instead of default the LAST matching.
  3549. // TODO: more common regex for the attribute name.
  3550. // See http://www.w3.org/TR/html-markup/syntax.html#syntax-attributes:
  3551. // Attribute names must consist of one or more characters other than the space
  3552. // characters, U+0000 NULL, """, "'", ">", "/", "=", the control characters,
  3553. // and any characters that are not defined by Unicode.
  3554. // An important example is attribute name with "-" in the middle: "data-sometext"
  3555. matches = /^\s*(\w+[\w|\-]*)\s*=\s*([\"|\'])(.*?)\2(.*)/.exec(attrStr);
  3556. if (matches === null || matches.length < 5) {
  3557. if (!tilteValue && cm.title) {
  3558. tilteValue = cellValue;
  3559. }
  3560. return rest + " style='" + encodeAttr(styleValue) + "'" +
  3561. (classes ? " class='" + encodeAttr(classes) + "'" : "") +
  3562. (tilteValue ? " title='" + encodeAttr(tilteValue) + "'" : "");
  3563. }
  3564. value = matches[3];
  3565. attrStr = matches[4];
  3566. switch (matches[1].toLowerCase()) { // attribute name
  3567. case "class":
  3568. // if some special characters are inside of class value there MUST be escaped
  3569. // so we can use any quote characters (' or ") around the call value.
  3570. // So we don't need to save quote used in class attribute
  3571. if (classes) {
  3572. classes += " " + value;
  3573. } else {
  3574. classes = value;
  3575. }
  3576. break;
  3577. case "title":
  3578. //quotedTilteValue = quote + value + quote;
  3579. tilteValue = value;
  3580. break;
  3581. case "style":
  3582. styleValue += value;
  3583. break;
  3584. default:
  3585. // matches[2] is quote
  3586. rest += " " + matches[1] + "=" + matches[2] + value + matches[2];
  3587. break;
  3588. }
  3589. }
  3590. }
  3591. }
  3592. result = styleValue !== "" ? "style='" + styleValue + "'" : "";
  3593. result += (classes !== undefined ? (" class='" + classes + "'") : "") + ((cm.title && cellValue) ? (" title='" + stripHtml(tv).replace(/'/g, "&apos;") + "'") : "");
  3594. result += rest;
  3595. return result;
  3596. },
  3597. cellVal = function (val) {
  3598. return val == null || val === "" ? "&#160;" : (p.autoencode ? htmlEncode(val) : String(val));
  3599. },
  3600. normalizeTreeGridProperties = function (ldat) {
  3601. var treeReader = p.treeReader,
  3602. loaded = treeReader.loaded,
  3603. isLeaf = treeReader.leaf_field,
  3604. expanded = treeReader.expanded_field,
  3605. getBool = function (val) {
  3606. return val === true || val === "true" || val === "1";
  3607. };
  3608. if (p.treeGridModel === "nested" && !ldat[isLeaf]) {
  3609. var lft = parseInt(ldat[treeReader.left_field], 10),
  3610. rgt = parseInt(ldat[treeReader.right_field], 10);
  3611. ldat[isLeaf] = (rgt === lft + 1) ? true : false;
  3612. }
  3613. if (ldat[loaded] !== undefined) {
  3614. ldat[loaded] = getBool(ldat[loaded]);
  3615. }
  3616. ldat[isLeaf] = getBool(ldat[isLeaf]);
  3617. ldat[expanded] = getBool(ldat[expanded]);
  3618. // the next line is suspected. The local data which missing loaded property
  3619. // can be be changed to have expanded=false
  3620. // we comment it.
  3621. //ldat[expanded] = ldat[expanded] && (ldat[loaded] || ldat[loaded] === undefined);
  3622. },
  3623. formatter = function (rowId, cellval, colpos, rwdat, act, rdata) {
  3624. var cm = p.colModel[colpos], v;
  3625. if (cm.formatter !== undefined) {
  3626. rowId = String(p.idPrefix) !== "" ? stripGridPrefix(rowId) : rowId;
  3627. var opts = { rowId: rowId, colModel: cm, gid: p.id, pos: colpos, rowData: rdata || rwdat };
  3628. if (isFunction(cm.cellBuilder)) {
  3629. v = cm.cellBuilder.call(ts, cellval, opts, rwdat, act);
  3630. } else if (isFunction(cm.formatter)) {
  3631. v = cm.formatter.call(ts, cellval, opts, rwdat, act);
  3632. } else if ($.fmatter) {
  3633. v = $.fn.fmatter.call(ts, cm.formatter, cellval, opts, rwdat, act);
  3634. } else {
  3635. v = cellVal(cellval);
  3636. }
  3637. } else {
  3638. v = cellVal(cellval);
  3639. }
  3640. v = cm.autoResizable && cm.formatter !== "actions" ? "<span class='" + p.autoResizing.wrapperClassName + "'>" + v + "</span>" : v;
  3641. if (p.treeGrid && act !== "edit" && ((p.ExpandColumn == null && colpos === 0) || (p.ExpandColumn === cm.name))) {
  3642. if (rdata == null) { rdata = p.data[p._index[rowId]]; }
  3643. var curLevel = parseInt(rdata[p.treeReader.level_field] || 0, 10), levelOffset = 18,
  3644. rootLevel = parseInt(p.tree_root_level, 10),
  3645. lftpos = rootLevel === 0 ? curLevel : curLevel - 1,
  3646. isLeaf = rdata[p.treeReader.leaf_field],
  3647. isExpanded = rdata[p.treeReader.expanded_field],
  3648. icon = rdata[p.treeReader.icon_field],
  3649. iconClass = isLeaf ?
  3650. ((icon != null && icon !== "") ? icon : p.treeIcons.leaf) + " tree-leaf" :
  3651. (isExpanded ? p.treeIcons.minus + " tree-minus" : p.treeIcons.plus + " tree-plus");
  3652. //normalizeTreeGridProperties(rdata); // ??? don't needed more probably
  3653. if (!isLeaf && icon && typeof icon === "string") {
  3654. var icons = icon.split(",");
  3655. if (icons.length === 2) {
  3656. iconClass = isExpanded ? icons[0] : icons [1];
  3657. }
  3658. }
  3659. v = "<div class='tree-wrap' style='width:" + ((lftpos + 1) * levelOffset) +
  3660. "px;'><div class='" +
  3661. mergeCssClasses(p.treeIcons.commonIconClass, iconClass, "treeclick") +
  3662. "' style='" +
  3663. (p.ExpandColClick === true ? "cursor:pointer;" : "") +
  3664. (p.direction === "rtl" ? "margin-right:" : "margin-left:") +
  3665. (lftpos * levelOffset) + "px;'></div></div>" +
  3666. "<span class='cell-wrapper" + (isLeaf ? "leaf" : "") + "'" +
  3667. (p.ExpandColClick ? " style='cursor:pointer;'" : "") + ">" +
  3668. v + "</span>";
  3669. }
  3670. return v;
  3671. },
  3672. emptyRows = function (scroll, locdata) {
  3673. var self = this, bDiv = grid.bDiv,
  3674. frozenTable = grid.fbDiv != null ?
  3675. grid.fbDiv.children(".ui-jqgrid-btable")[0] : null,
  3676. removeRows = function (table) {
  3677. if (!table) { return; }
  3678. var tableRows = table.rows, firstrow = tableRows[0];
  3679. if (p.deepempty) {
  3680. if (tableRows) { $(tableRows).slice(1).remove(); }
  3681. } else if (p.quickEmpty) {
  3682. if (p.quickEmpty === "quickest") {
  3683. table.replaceChild(document.createElement("tbody"), table.tBodies[0]);
  3684. table.firstChild.appendChild(firstrow);
  3685. } else {
  3686. while (tableRows.length > 1) { // skip deliting of the first row
  3687. table.deleteRow(tableRows.length - 1);
  3688. }
  3689. }
  3690. } else {
  3691. $(table.firstChild).empty().append(firstrow);
  3692. }
  3693. };
  3694. $(self).off(".jqGridFormatter");
  3695. removeRows(self);
  3696. removeRows(frozenTable);
  3697. if (scroll && p.scroll) {
  3698. $(bDiv.firstChild).css({ height: "auto" });
  3699. $(bDiv.firstChild.firstChild).css({ height: 0, display: "none" });
  3700. if (bDiv.scrollTop !== 0) {
  3701. bDiv.scrollTop = 0;
  3702. }
  3703. }
  3704. if (locdata === true && p.treeGrid) {
  3705. clearArray(p.data); //p.data = [];
  3706. clearArray(p.lastSelectedData); //p.lastSelectedData = [];
  3707. p._index = {};
  3708. p.dataIndexById = {};
  3709. p.indexByColumnData = {};
  3710. }
  3711. p.rowIndexes = {};
  3712. p.iRow = -1;
  3713. p.iCol = -1;
  3714. //$(self.grid.headers).each(function () { $(this.el).removeData("autoResized"); });
  3715. },
  3716. addItemDataToColumnIndex = function (rd, id) {
  3717. var cmName, v;
  3718. for (cmName in p.indexByColumnData) {
  3719. if (p.indexByColumnData.hasOwnProperty(cmName)) {
  3720. v = rd[cmName];
  3721. if (rd.hasOwnProperty(cmName) && v !== undefined && v !== "") {
  3722. // rd[cmName] is the value, which need be saved in p.indexByColumnData[cmName]
  3723. if (p.ignoreCase) {
  3724. v = String(v).toLowerCase();
  3725. }
  3726. if (p.indexByColumnData[cmName][v] === undefined) {
  3727. p.indexByColumnData[cmName][v] = {};
  3728. }
  3729. p.indexByColumnData[cmName][v][id] = rd[cmName];
  3730. if (p.dataIndexById[id] === undefined) {
  3731. p.dataIndexById[id] = {};
  3732. }
  3733. if (p.dataIndexById[id][cmName] === undefined) {
  3734. p.dataIndexById[id][cmName] = {};
  3735. }
  3736. p.dataIndexById[id][cmName][v] = p.indexByColumnData[cmName][v];
  3737. }
  3738. }
  3739. }
  3740. },
  3741. removeItemDataFromColumnIndex = function (id) {
  3742. var cmName, columnIndex, v, index = p.dataIndexById[id];
  3743. if (index == null) {
  3744. return;
  3745. }
  3746. for (cmName in index) {
  3747. if (index.hasOwnProperty(cmName)) {
  3748. columnIndex = index[cmName];
  3749. for (v in columnIndex) {
  3750. if (columnIndex.hasOwnProperty(v)) {
  3751. delete p.indexByColumnData[cmName][v][id];
  3752. if ($.isEmptyObject(p.indexByColumnData[cmName][v])) {
  3753. delete p.indexByColumnData[cmName][v];
  3754. }
  3755. }
  3756. }
  3757. }
  3758. }
  3759. delete p.dataIndexById[id];
  3760. },
  3761. normalizeData = function () {
  3762. var data = p.data, dataLength = data.length, i, cur, cells, idName, idIndex, v, rd, id,
  3763. localReader = p.localReader, additionalProperties = p.additionalProperties,
  3764. cellName = localReader.cell, cmName, isArrayCells, addProp, info,
  3765. arrayReaderInfos = p.arrayReaderInfos;
  3766. if (p.datatype !== "local" || localReader.repeatitems !== true) {
  3767. if (p.treeGrid) {
  3768. for (i = 0; i < dataLength; i++) {
  3769. normalizeTreeGridProperties(data[i]);
  3770. }
  3771. }
  3772. return; // nothing to do
  3773. }
  3774. idName = p.keyName === false ?
  3775. (isFunction(localReader.id) ? localReader.id.call(ts, data) : localReader.id) :
  3776. p.keyName;
  3777. if (!isNaN(idName)) {
  3778. idIndex = Number(idName);
  3779. /*for (cmName in arrayReaderInfos) {
  3780. if (arrayReaderInfos.hasOwnProperty(cmName)) {
  3781. info = arrayReaderInfos[cmName];
  3782. if (info.order === idIndex) {
  3783. idName = info.name;
  3784. break;
  3785. }
  3786. }
  3787. }*/
  3788. } else if (!isFunction(idName)) {
  3789. if (p.arrayReaderInfos[idName] != null) {
  3790. idIndex = p.arrayReaderInfos[idName].order;
  3791. }
  3792. }
  3793. for (i = 0; i < dataLength; i++) {
  3794. cur = data[i];
  3795. cells = cellName ? getAccessor(cur, cellName) || cur : cur;
  3796. isArrayCells = isArray(cells);
  3797. rd = {};
  3798. for (cmName in arrayReaderInfos) {
  3799. if (arrayReaderInfos.hasOwnProperty(cmName)) {
  3800. info = arrayReaderInfos[cmName];
  3801. v = getAccessor(cells, isArrayCells ? info.order : info.name);
  3802. if (info.type === 1) { // additional property
  3803. addProp = additionalProperties[info.index];
  3804. if (addProp != null && isFunction(addProp.convert)) {
  3805. v = addProp.convert(v, cells);
  3806. }
  3807. }
  3808. if (v !== undefined) {
  3809. rd[cmName] = v;
  3810. }
  3811. }
  3812. }
  3813. // read id.
  3814. if (rd[idName] !== undefined) {
  3815. // in case of p.keyName or if there exist column with the same id name
  3816. // probably one should test only for rd[p.keyName] !== undefined
  3817. // and get rd[p.keyName] below, but the probability that the user
  3818. // wanted to use the column rd[idName] as the rowid seemd me
  3819. // higher as the opposite case.
  3820. // the id should be already read in p.keyName column.
  3821. // One need generate id only if the input data had no id
  3822. id = rd[idName] !== undefined ? rd[idName] : randId(); //id = br + i;
  3823. } else {
  3824. id = getAccessor(cur, isArray(cur) ? idIndex : idName);
  3825. if (id === undefined) {
  3826. id = getAccessor(cells, isArray(cells) ? idIndex : idName);
  3827. }
  3828. if (id === undefined) {
  3829. id = randId(); //id = br + i;
  3830. }
  3831. }
  3832. id = String(id);
  3833. rd[localReader.id] = id; //p.idPrefix + id;
  3834. // the next two line are the most important!
  3835. // one should consider to remove true parameter to improve the performance !!!
  3836. if (p.treeGrid) { normalizeTreeGridProperties(rd); }
  3837. extend(data[i], rd); // extend(true, data[i], rd);
  3838. }
  3839. },
  3840. refreshIndex = function () {
  3841. var datalen = p.data.length, idname, i, val, item;
  3842. if (p.keyName === false || (p.loadonce && p.dataTypeOrg)) {
  3843. idname = p.localReader.id;
  3844. } else {
  3845. idname = p.keyName;
  3846. }
  3847. p._index = {};
  3848. p.dataIndexById = {};
  3849. p.indexByColumnData = buildEmptyIndexedColumnMap();
  3850. for (i = 0; i < datalen; i++) {
  3851. item = p.data[i];
  3852. val = getAccessor(item, idname);
  3853. if (val === undefined) {
  3854. val = String(randId()); //String(i + 1);
  3855. if (item[idname] === undefined) {
  3856. item[idname] = val;
  3857. }
  3858. }
  3859. p._index[val] = i;
  3860. addItemDataToColumnIndex.call(this, item, val);
  3861. }
  3862. },
  3863. constructTr = function (id, hide, altClass, rd, cur, selected) {
  3864. var tabindex = "-1", restAttr = "", attrName, style = hide ? "display:none;" : "", self = this,
  3865. classes = getGuiStyles("gridRow", "jqgrow ui-row-" + p.direction) + (altClass ? " " + altClass : "") + (selected ? " " + getGuiStyles("states.select") : ""),
  3866. rowAttrObj = $(self).triggerHandler("jqGridRowAttr", [rd, cur, id]);
  3867. if (typeof rowAttrObj !== "object") {
  3868. rowAttrObj = isFunction(p.rowattr) ? p.rowattr.call(self, rd, cur, id) :
  3869. (typeof p.rowattr === "string" && jgrid.rowattr != null && isFunction(jgrid.rowattr[p.rowattr]) ?
  3870. jgrid.rowattr[p.rowattr].call(self, rd, cur, id) : {});
  3871. }
  3872. if (rowAttrObj != null && !$.isEmptyObject(rowAttrObj)) {
  3873. if (rowAttrObj.hasOwnProperty("id")) {
  3874. id = rowAttrObj.id;
  3875. delete rowAttrObj.id;
  3876. }
  3877. if (rowAttrObj.hasOwnProperty("tabindex")) {
  3878. tabindex = rowAttrObj.tabindex;
  3879. delete rowAttrObj.tabindex;
  3880. }
  3881. if (rowAttrObj.hasOwnProperty("style")) {
  3882. style += rowAttrObj.style;
  3883. delete rowAttrObj.style;
  3884. }
  3885. if (rowAttrObj.hasOwnProperty("class")) {
  3886. classes += " " + rowAttrObj["class"];
  3887. delete rowAttrObj["class"];
  3888. }
  3889. // don't allow to change role attribute
  3890. try { delete rowAttrObj.role; } catch (ignore) { }
  3891. for (attrName in rowAttrObj) {
  3892. if (rowAttrObj.hasOwnProperty(attrName)) {
  3893. restAttr += " " + attrName + "=" + rowAttrObj[attrName];
  3894. }
  3895. }
  3896. }
  3897. if (p.treeGrid) {
  3898. if (parseInt(rd[p.treeReader.level_field], 10) !== parseInt(p.tree_root_level, 10)) {
  3899. var pn = $j.getNodeParent.call($(this), rd),
  3900. expan = pn && pn.hasOwnProperty(p.treeReader.expanded_field) ?
  3901. pn[p.treeReader.expanded_field] : true;
  3902. if (!expan && !hide) {
  3903. // TODO: append ";" to style if required
  3904. style += "display:none;";
  3905. }
  3906. }
  3907. }
  3908. return "<tr role='row' id='" + id + "' tabindex='" + tabindex + "' class='" + classes + "'" +
  3909. (style === "" ? "" : " style='" + style + "'") + restAttr + ">";
  3910. },
  3911. finalizationFormatters = function () {
  3912. var i, formatName, fmatter = $.fn.fmatter;
  3913. for (i = 0; i < p.colModel.length; i++) {
  3914. formatName = p.colModel[i].formatter;
  3915. if (typeof formatName === "string" && fmatter != null &&
  3916. isFunction(fmatter[formatName]) && isFunction(fmatter[formatName].pageFinalization)) {
  3917. fmatter[formatName].pageFinalization.call(this, i);
  3918. }
  3919. }
  3920. },
  3921. fillOrClearCellBuilder = function (clear, act) {
  3922. var i, cm, colModel = p.colModel, n = colModel.length, opt,
  3923. autoencodeCellBuilder = function (v) {
  3924. return v == null || v === "" ? "&#160;" : htmlEncode(v);
  3925. },
  3926. simpleCellBuilder = function (v) {
  3927. return v == null || v === "" ? "&#160;" : String(v);
  3928. };
  3929. for (i = 0; i < n; i++) {
  3930. cm = colModel[i];
  3931. cm.cellBuilder = null;
  3932. if (!clear) {
  3933. opt = { colModel: cm, gid: p.id, pos: i };
  3934. if (cm.formatter === undefined) {
  3935. cm.cellBuilder = p.autoencode ? autoencodeCellBuilder : simpleCellBuilder;
  3936. } else if (typeof cm.formatter === "string" && $.fn.fmatter != null && isFunction($.fn.fmatter.getCellBuilder)) {
  3937. cm.cellBuilder = $.fn.fmatter.getCellBuilder.call(ts, cm.formatter, opt, act || "add");
  3938. } else if (isFunction(cm.getCellBuilder)) {
  3939. cm.cellBuilder = cm.getCellBuilder.call(ts, opt, act || "add");
  3940. }
  3941. }
  3942. }
  3943. },
  3944. readInput = function (data, rcnt, more, adjust) {
  3945. var self = this, $self = $(self), startReq = new Date(), datatype = p.datatype,
  3946. // readAllInputData shows that one should read ALL input items, not only the current page of data
  3947. readAllInputData = (datatype !== "local" && p.loadonce) || datatype === "xmlstring" || datatype === "jsonstring",
  3948. isXML = (datatype === "xmlstring" || datatype === "xml") && $.isXMLDoc(data),
  3949. locid = "_id_", dataReader = p.localReader, fieldReader = getAccessor;
  3950. if (data) {
  3951. if (datatype === "xml" && !isXML) {
  3952. return;
  3953. }
  3954. if (p.treeANode === -1 && !p.scroll) {
  3955. grid.emptyRows.call(self, false, true);
  3956. rcnt = 1;
  3957. } else {
  3958. rcnt = rcnt > 1 ? rcnt : 1;
  3959. }
  3960. } else {
  3961. // in case of usage TreeGrid for example
  3962. return;
  3963. }
  3964. if (readAllInputData) {
  3965. clearArray(p.data); //p.data = [];
  3966. clearArray(p.lastSelectedData); //p.lastSelectedData = [];
  3967. p._index = {};
  3968. if (p.grouping && p.groupingView != null) {
  3969. p.groupingView.groups = [];
  3970. p.groupingView._locgr = false;
  3971. }
  3972. p.localReader.id = locid; // consider to place the statement in if (p.treeGrid) {...}
  3973. }
  3974. p.reccount = 0;
  3975. switch (datatype) {
  3976. case "xml":
  3977. case "xmlstring":
  3978. dataReader = p.xmlReader;
  3979. fieldReader = jgrid.getXmlData;
  3980. break;
  3981. case "json":
  3982. case "jsonp":
  3983. case "jsonstring":
  3984. dataReader = p.jsonReader;
  3985. break;
  3986. default:
  3987. break;
  3988. }
  3989. var i, cells, len, drows, idName, idIndex, rd = {}, idr,
  3990. colModel = p.colModel, nCol = colModel.length, cmName,
  3991. iChild, children, nChildren, child,
  3992. // TODO: consider to introduce preloadedAttributes in the same way
  3993. // like we use to preloadedNodes below and to cache .attributes[i]
  3994. // in the same way like one cache .childNodes[i].
  3995. // One should measure the performance, to find out whether
  3996. // such caching will improve the performance.
  3997. arrayReaderInfos = p.arrayReaderInfos, info, preloadedNodes = {},
  3998. attrReader = function (nodeName) {
  3999. return function (obj) {
  4000. var attrValue = obj != null && isFunction(obj.getAttribute) ? obj.getAttribute(nodeName) : null;
  4001. return attrValue !== null ? attrValue : undefined;
  4002. };
  4003. },
  4004. nodeReader = function (nodeName) {
  4005. return function () {
  4006. // commented code which used getElementsByTagName works
  4007. // good in new web browsers (Chrome, Firefox, Safari),
  4008. // but it is slowly in IE10 and especially in IE8.
  4009. // So we use the code which is very good for all web browsers
  4010. /*var elem = obj.getElementsByTagName(nodeName)[0], childNodes;
  4011. if (elem != null) {
  4012. childNodes = elem.childNodes;
  4013. return childNodes.length > 0 ? childNodes[0].nodeValue : undefined;
  4014. }
  4015. return undefined;*/
  4016. var elem = preloadedNodes[nodeName], childNodes;
  4017. if (elem == null) { return undefined; }
  4018. childNodes = elem.childNodes;
  4019. return childNodes.length > 0 ? childNodes[0].nodeValue : undefined;
  4020. };
  4021. };
  4022. p.page = intNum(fieldReader(data, dataReader.page), p.page);
  4023. p.lastpage = intNum(fieldReader(data, dataReader.total), 1);
  4024. p.records = intNum(fieldReader(data, dataReader.records));
  4025. if (isFunction(dataReader.userdata)) {
  4026. p.userData = dataReader.userdata.call(self, data) || {};
  4027. } else if (isXML) {
  4028. fieldReader(data, dataReader.userdata, true)
  4029. .each(function () {
  4030. p.userData[this.getAttribute("name")] = $(this).text();
  4031. });
  4032. } else {
  4033. p.userData = fieldReader(data, dataReader.userdata) || {};
  4034. }
  4035. // fill colReader and
  4036. fillOrClearCellBuilder();
  4037. var colReader = {}, isArrayCells, v, addProp, items,
  4038. additionalProperties = p.additionalProperties,
  4039. setSimpleColReaderIfPossible = function (propName, nameReaderOrAddProp) {
  4040. if (isXML && typeof nameReaderOrAddProp === "string") {
  4041. if (/^\w+$/.test(nameReaderOrAddProp)) {
  4042. colReader[propName] = nodeReader(nameReaderOrAddProp);
  4043. } else if (/^\[\w+\]$/.test(nameReaderOrAddProp)) {
  4044. colReader[propName] = attrReader(nameReaderOrAddProp.substring(1, nameReaderOrAddProp.length - 1));
  4045. }
  4046. }
  4047. },
  4048. colReaderFilling = function (colOrAddProp) {
  4049. var colOrAddPropName = colOrAddProp.name,
  4050. nameReader = isXML ?
  4051. colOrAddProp.xmlmap || colOrAddPropName :
  4052. (datatype === "local" && !p.dataTypeOrg) || datatype === "jsonstring" || datatype === "json" || datatype === "jsonp" ? colOrAddProp.jsonmap || colOrAddPropName : colOrAddPropName;
  4053. if (p.keyName !== false && colOrAddProp.key === true) {
  4054. p.keyName = colOrAddPropName; // TODO: replace nameReader to colOrAddPropName if we don't will read it at the second time
  4055. }
  4056. if (typeof nameReader === "string" || isFunction(nameReader)) {
  4057. colReader[colOrAddPropName] = nameReader;
  4058. }
  4059. if (!isFunction(nameReader)) {
  4060. setSimpleColReaderIfPossible(colOrAddPropName, nameReader);
  4061. }
  4062. };
  4063. for (i = 0; i < nCol; i++) {
  4064. colReaderFilling(colModel[i]);
  4065. }
  4066. nCol = additionalProperties.length;
  4067. for (i = 0; i < nCol; i++) {
  4068. addProp = additionalProperties[i];
  4069. if (typeof addProp === "object" && addProp != null) {
  4070. colReaderFilling(addProp);
  4071. } else {
  4072. setSimpleColReaderIfPossible(addProp, addProp);
  4073. }
  4074. }
  4075. // TODO: Consider to allow to specify key:true property in additionalProperties
  4076. // in the case the item of additionalProperties should looks not like
  4077. // "myProp" and not like {name: "myProp", convert: function (data) {...}} used in TreeGrid,
  4078. // but in more common form {name: "myProp", key:true, convert: function (data) {...}}
  4079. // prepare to read id of data items
  4080. // if p.keyName !== false it contains the name of the column or the nameReader functoin (jsonmap or xmlmap)
  4081. // in the case the reading of id is simple and one DON'T NEED TO READ IT AT ALL
  4082. // because it will be already read during reading of the columns
  4083. idName = p.keyName === false ?
  4084. (isFunction(dataReader.id) ? dataReader.id.call(self, data) : dataReader.id) :
  4085. p.keyName;
  4086. if (!isNaN(idName)) {
  4087. idIndex = Number(idName);
  4088. } else if (!isFunction(idName)) {
  4089. if (arrayReaderInfos[idName]) {
  4090. idIndex = arrayReaderInfos[idName].order;
  4091. }
  4092. if (isXML && p.keyName === false) {
  4093. if (typeof idName === "string" && /^\[\w+\]$/.test(idName)) {
  4094. idName = attrReader(idName.substring(1, idName.length - 1));
  4095. } else if (typeof idName === "string" && /^\w+$/.test(idName)) {
  4096. idName = nodeReader(idName);
  4097. }
  4098. }
  4099. }
  4100. // get array of items from the input data
  4101. drows = fieldReader(data, dataReader.root, true);
  4102. if (dataReader.row) {
  4103. if (drows.length === 1 && typeof dataReader.row === "string" && /^\w+$/.test(dataReader.row)) {
  4104. items = [];
  4105. children = drows[0].childNodes;
  4106. nChildren = children.length;
  4107. for (iChild = 0; iChild < nChildren; iChild++) {
  4108. child = children[iChild];
  4109. if (child.nodeType === 1 && child.nodeName === dataReader.row) {
  4110. items.push(child);
  4111. }
  4112. }
  4113. drows = items;
  4114. } else {
  4115. drows = fieldReader(drows, dataReader.row, true); // || [];
  4116. }
  4117. }
  4118. if (drows == null && isArray(data)) { drows = data; }
  4119. if (!drows) { drows = []; }
  4120. len = drows.length;
  4121. if (len > 0 && p.page <= 0) { p.page = 1; }
  4122. var rn = parseInt(p.rowNum, 10); // br = p.scroll ? randId() : 1
  4123. if (adjust) { rn *= adjust + 1; }
  4124. // The first loop (from 0 till len) read ALL data and saves it in array
  4125. var cellsToDisplay = [], ids = [], id, cur;
  4126. items = [];
  4127. for (i = 0; i < len; i++) {
  4128. cur = drows[i];
  4129. cells = dataReader.repeatitems && dataReader.cell ? fieldReader(cur, dataReader.cell, true) || cur : cur;
  4130. isArrayCells = dataReader.repeatitems && (isXML || isArray(cells));
  4131. // the first step: reading the input data from the current item
  4132. rd = {}; // require to prevent modification of items previously placed in p.data
  4133. preloadedNodes = {};
  4134. if (isXML && !isArrayCells && cells != null) {
  4135. // reading of simple children nodes by name can be relatively slow
  4136. // because one enumerates all children nodes to find the node with
  4137. // specified name
  4138. children = cells.childNodes;
  4139. nChildren = children.length;
  4140. for (iChild = 0; iChild < nChildren; iChild++) {
  4141. child = children[iChild];
  4142. if (child.nodeType === 1) {
  4143. preloadedNodes[child.nodeName] = child;
  4144. }
  4145. }
  4146. // TODO: one can consider to examine cells.attributes and
  4147. // to save all values in preloadedAttributes map.
  4148. }
  4149. for (cmName in arrayReaderInfos) {
  4150. if (arrayReaderInfos.hasOwnProperty(cmName)) {
  4151. info = arrayReaderInfos[cmName];
  4152. if (isArrayCells) {
  4153. v = cells[info.order];
  4154. if (isXML && v != null) {
  4155. v = v.textContent || v.text;
  4156. }
  4157. } else if (colReader[cmName] != null && typeof colReader[cmName] !== "string") { // isFunction(colReader[cmName])
  4158. v = colReader[cmName].call(self, cells, { cmName: cmName, iItem: i });
  4159. } else {
  4160. v = fieldReader(cells, typeof colReader[cmName] === "string" ? colReader[cmName] : info.name);
  4161. }
  4162. if (info.type === 1) { // additional property
  4163. addProp = additionalProperties[info.index];
  4164. if (addProp != null && isFunction(addProp.convert)) {
  4165. v = addProp.convert(v, cells);
  4166. }
  4167. }
  4168. if (v !== undefined) {
  4169. rd[cmName] = v;
  4170. }
  4171. }
  4172. }
  4173. // read id.
  4174. if (rd[idName] !== undefined) {
  4175. // the id should be already read in p.keyName column.
  4176. // One need generate id only if the input data had no id
  4177. id = rd[idName] !== undefined ? rd[idName] : randId(); //id = br + i;
  4178. } else {
  4179. id = fieldReader(cur, isArray(cur) ? idIndex : idName);
  4180. if (id === undefined) {
  4181. id = fieldReader(cells, isArray(cells) ? idIndex : idName);
  4182. }
  4183. if (id === undefined) {
  4184. id = randId(); //id = br + i;
  4185. }
  4186. }
  4187. if (rd[idName] === undefined) {
  4188. rd[idName] = id;
  4189. }
  4190. id = String(id);
  4191. idr = p.idPrefix + id;
  4192. if (p.treeGrid) { normalizeTreeGridProperties(rd); }
  4193. // final steps of reading the row
  4194. if (i < rn) {
  4195. ids.push(idr);
  4196. cellsToDisplay.push(cells);
  4197. items.push(rd);
  4198. } else if (!readAllInputData) {
  4199. break;
  4200. }
  4201. if (readAllInputData || p.treeGrid === true) {
  4202. rd[locid] = id; //stripGridPrefix(idr);
  4203. p.data.push(rd);
  4204. addItemDataToColumnIndex(rd, id);
  4205. p._index[rd[locid]] = p.data.length - 1;
  4206. }
  4207. }
  4208. if (readAllInputData && p.treeGrid !== true) {
  4209. if (p.forceClientSorting) {
  4210. // don't display the data, just read it.
  4211. return;
  4212. }
  4213. // initialize lastSelectedData to simplify the usage of lastSelectedData
  4214. p.lastSelectedData = p.data.slice();
  4215. }
  4216. // of rd items plus array cells items (almost the same as drows).
  4217. // The second loop (from 0 till min(len,rn)) will build rowData from the both arrays
  4218. // Then one place rowData AT ONCE to the body any calls afterInsertRow in the loop
  4219. // for every inserted row.
  4220. // Finally one clean up the both arrays
  4221. var rowData = jgrid.parseDataToHtml.call(self, len, ids, items, cellsToDisplay, rcnt, adjust, readAllInputData);
  4222. fillOrClearCellBuilder(true); // clear cellBuilders
  4223. // place the HTML string fragments collected in rowData in the body of grid
  4224. var fpos = p.treeANode > -1 ? p.treeANode : 0;
  4225. var $tbody = $(self.tBodies[0]);
  4226. if (p.treeGrid === true && fpos > 0) {
  4227. $(self.rows[fpos]).after(rowData.join(""));
  4228. } else if (p.scroll) {
  4229. $tbody.append(rowData.join(""));
  4230. } else if (self.firstElementChild == null || (document.documentMode !== undefined && document.documentMode <= 9)) {
  4231. // for IE8 for example
  4232. $tbody.html($tbody.html() + rowData.join("")); // append to innerHTML of tbody which contains the first row (.jqgfirstrow)
  4233. self.grid.cols = self.rows[0].cells; // update cached first row
  4234. } else {
  4235. self.firstElementChild.innerHTML += rowData.join(""); // append to innerHTML of tbody which contains the first row (.jqgfirstrow)
  4236. self.grid.cols = self.rows[0].cells; // update cached first row
  4237. }
  4238. // refresh rowIndexes cash in case of usage grouping
  4239. if (p.grouping) {
  4240. rebuildRowIndexes.call(self);
  4241. // bind onclick on +/- icon of grouping header to the call of groupingToggle
  4242. var expandOrCollapseGroup = function (e) {
  4243. var groupHeaderId = $(this).closest("tr.jqgroup").attr("id");
  4244. $self.jqGrid("groupingToggle", groupHeaderId, this, e);
  4245. return false;
  4246. },
  4247. $tr;
  4248. for (i = 0; i < self.rows.length; i++) {
  4249. $tr = $(self.rows[i]);
  4250. if ($tr.hasClass("jqgroup")) {
  4251. $tr.children("td")
  4252. .children("span.tree-wrap")
  4253. .click(expandOrCollapseGroup);
  4254. }
  4255. }
  4256. }
  4257. //
  4258. if (p.subGrid === true) {
  4259. // make subgrid specific actions: bind click event handler to "+"
  4260. try { $j.addSubGrid.call($self, p.iColByName.subgrid); } catch (ignore) { }
  4261. }
  4262. if (p.gridview === false || isFunction(p.afterInsertRow)) {
  4263. for (i = 0; i < Math.min(len, rn); i++) {
  4264. feedback.call(self, "afterInsertRow", ids[i], items[i], cellsToDisplay[i]);
  4265. }
  4266. }
  4267. p.totaltime = new Date() - startReq;
  4268. if (i > 0) {
  4269. if (p.records === 0) { p.records = len; }
  4270. }
  4271. clearArray(rowData);
  4272. if (p.treeGrid === true) {
  4273. try { $j.setTreeNode.call($self, fpos + 1, i + fpos + 1); } catch (ignore) { }
  4274. }
  4275. p.reccount = Math.min(len, rn);
  4276. p.treeANode = -1;
  4277. if (p.userDataOnFooter) { $j.footerData.call($self, "set", p.userData, true); }
  4278. if (readAllInputData) {
  4279. p.records = len;
  4280. p.lastpage = Math.ceil(len / rn);
  4281. }
  4282. if (!more) { self.updatepager(false, true); }
  4283. finalizationFormatters.call(self);
  4284. },
  4285. addLocalData = function () {
  4286. var $self = $(this), st = p.multiSort ? [] : "", sto = {}, fndsort = false, cmtypes = {}, grtypes = [], grindexes = [],
  4287. defSrcFormat = getRes("formatter.date.srcformat"),
  4288. defNewFormat = getRes("formatter.date.newformat");
  4289. if (!isArray(p.data)) {
  4290. return {};
  4291. }
  4292. if (p.multiSort) {
  4293. getSortNames(st, sto);
  4294. }
  4295. var grpview = p.grouping ? p.groupingView : false, lengrp, gin,
  4296. processColModel = function (cm, iCol1, isAddProp) {
  4297. var srcformat, newformat,
  4298. grindex = cm.index || cm.name,
  4299. sorttype = cm.sorttype || "text";
  4300. cmtypes[cm.name] = {
  4301. reader: !p.dataTypeOrg ? cm.jsonmap || cm.name : cm.name,
  4302. iCol: iCol1,
  4303. stype: sorttype,
  4304. srcfmt: "",
  4305. newfmt: "",
  4306. sfunc: cm.sortfunc || null,
  4307. isAddProp: isAddProp === true ? true : false
  4308. };
  4309. if (sorttype === "date" || sorttype === "datetime") {
  4310. if (cm.formatter && typeof cm.formatter === "string" && cm.formatter === "date") {
  4311. if (cm.formatoptions && cm.formatoptions.srcformat) {
  4312. srcformat = cm.formatoptions.srcformat;
  4313. } else {
  4314. srcformat = defSrcFormat;
  4315. }
  4316. if (cm.formatoptions && cm.formatoptions.newformat) {
  4317. newformat = cm.formatoptions.newformat;
  4318. } else {
  4319. newformat = defNewFormat;
  4320. }
  4321. } else {
  4322. srcformat = newformat = cm.datefmt || "Y-m-d";
  4323. }
  4324. cmtypes[cm.name].srcfmt = srcformat;
  4325. cmtypes[cm.name].newfmt = newformat;
  4326. }
  4327. if (p.grouping) {
  4328. for (gin = 0, lengrp = grpview.groupField.length; gin < lengrp; gin++) {
  4329. if (cm.name === grpview.groupField[gin]) {
  4330. grtypes[gin] = cmtypes[grindex];
  4331. grindexes[gin] = grindex;
  4332. }
  4333. }
  4334. }
  4335. if (!p.multiSort) {
  4336. if (!fndsort && (cm.index === p.sortname || cm.name === p.sortname)) {
  4337. st = cm.name; // ???
  4338. fndsort = true;
  4339. }
  4340. }
  4341. };
  4342. each(p.colModel, function (iCol1) {
  4343. processColModel(this, iCol1);
  4344. });
  4345. each(p.additionalProperties, function (iCol1) {
  4346. processColModel(
  4347. typeof this === "string" ? { name: this } : this,
  4348. iCol1,
  4349. true
  4350. );
  4351. });
  4352. if (p.treeGrid) {
  4353. $j.SortTree.call($self, st, p.sortorder,
  4354. cmtypes[st] != null && cmtypes[st].stype ? cmtypes[st].stype : "text",
  4355. cmtypes[st] != null && cmtypes[st].srcfmt ? cmtypes[st].srcfmt : "");
  4356. return false;
  4357. }
  4358. var compareFnMap = {
  4359. "eq": function (queryObj) { return queryObj.equals; },
  4360. "ne": function (queryObj) { return queryObj.notEquals; },
  4361. "lt": function (queryObj) { return queryObj.less; },
  4362. "le": function (queryObj) { return queryObj.lessOrEquals; },
  4363. "gt": function (queryObj) { return queryObj.greater; },
  4364. "ge": function (queryObj) { return queryObj.greaterOrEquals; },
  4365. "cn": function (queryObj) { return queryObj.contains; },
  4366. "nc": function (queryObj, op) { return op === "OR" ? queryObj.orNot().contains : queryObj.andNot().contains; },
  4367. "bw": function (queryObj) { return queryObj.startsWith; },
  4368. "bn": function (queryObj, op) { return op === "OR" ? queryObj.orNot().startsWith : queryObj.andNot().startsWith; },
  4369. "en": function (queryObj, op) { return op === "OR" ? queryObj.orNot().endsWith : queryObj.andNot().endsWith; },
  4370. "ew": function (queryObj) { return queryObj.endsWith; },
  4371. "ni": function (queryObj, op) { return op === "OR" ? queryObj.orNot().inSet : queryObj.andNot().inSet; },
  4372. "in": function (queryObj) { return queryObj.inSet; },
  4373. "nu": function (queryObj) { return queryObj.isNull; },
  4374. "nn": function (queryObj, op) { return op === "OR" ? queryObj.orNot().isNull : queryObj.andNot().isNull; }
  4375. },
  4376. query = jgrid.from.call(this, p.data);
  4377. if (p.ignoreCase) { query = query.ignoreCase(); }
  4378. function tojLinq(group) {
  4379. var s = 0, index, gor, ror, opr, rule, r, cmi1;
  4380. if (group.groups != null) {
  4381. gor = group.groups.length && group.groupOp.toString().toUpperCase() === "OR";
  4382. if (gor) {
  4383. query.orBegin();
  4384. }
  4385. for (index = 0; index < group.groups.length; index++) {
  4386. if (s > 0 && gor) {
  4387. query.or();
  4388. }
  4389. try {
  4390. tojLinq(group.groups[index]);
  4391. } catch (e) { fatalErrorFunction(e); }
  4392. s++;
  4393. }
  4394. if (gor) {
  4395. query.orEnd();
  4396. }
  4397. }
  4398. if (group.rules != null) {
  4399. try {
  4400. ror = group.rules.length && group.groupOp.toString().toUpperCase() === "OR";
  4401. if (ror) {
  4402. query.orBegin();
  4403. }
  4404. for (index = 0; index < group.rules.length; index++) {
  4405. rule = group.rules[index];
  4406. opr = group.groupOp.toString().toUpperCase();
  4407. if (compareFnMap[rule.op] && rule.field) {
  4408. if (s > 0 && opr && opr === "OR") {
  4409. query = query.or();
  4410. }
  4411. cmi1 = cmtypes[rule.field];
  4412. if (cmi1 != null) {
  4413. r = cmi1.reader;
  4414. query = compareFnMap[rule.op](query, opr)(
  4415. isFunction(r) ?
  4416. "jQuery.jgrid.getAccessor(this,jQuery(\"" + p.idSel + "\")[0].p.colModel[" + cmi1.iCol + "].jsonmap)" :
  4417. "jQuery.jgrid.getAccessor(this,'" + r + "')",
  4418. rule.data,
  4419. cmtypes[rule.field]
  4420. );
  4421. }
  4422. } else if (p.customSortOperations != null && p.customSortOperations[rule.op] != null && isFunction(p.customSortOperations[rule.op].filter)) {
  4423. query = query.custom(rule.op, rule.field, rule.data);
  4424. }
  4425. s++;
  4426. }
  4427. if (ror) {
  4428. query.orEnd();
  4429. }
  4430. } catch (g) { fatalErrorFunction(g); }
  4431. }
  4432. }
  4433. if (p.search === true) {
  4434. var srules = p.postData[(p.searching || {}).sFilter || p.prmNames.filters];
  4435. if (srules) {
  4436. if (typeof srules === "string") { srules = $.parseJSON(srules); }
  4437. tojLinq(srules);
  4438. } else {
  4439. try {
  4440. var cmtypes1 = cmtypes[p.postData.searchField];
  4441. query = compareFnMap[p.postData.searchOper](query)(
  4442. //p.postData.searchField,
  4443. isFunction(cmtypes1.reader) ?
  4444. "jQuery.jgrid.getAccessor(this,jQuery(\"" + p.idSel + "\")[0].p.colModel[" + cmtypes1.iCol + "].jsonmap)" :
  4445. "jQuery.jgrid.getAccessor(this,'" + cmtypes1.reader + "')",
  4446. p.postData.searchString,
  4447. cmtypes[p.postData.searchField]
  4448. );
  4449. } catch (ignore) { }
  4450. }
  4451. }
  4452. if (p.grouping) {
  4453. for (gin = 0; gin < lengrp && gin < grindexes.length && gin < grtypes.length; gin++) {
  4454. query.orderBy(grindexes[gin], grpview.groupOrder[gin], grtypes[gin].stype, grtypes[gin].srcfmt);
  4455. }
  4456. }
  4457. if (p.multiSort) {
  4458. each(st, function () {
  4459. query.orderBy(this, sto[this], cmtypes[this].stype, cmtypes[this].srcfmt, cmtypes[this].sfunc);
  4460. });
  4461. } else if (st && p.sortorder && fndsort) {
  4462. query.orderBy(p.sortname, p.sortorder.toUpperCase() === "DESC" ? "d" : "a", cmtypes[st].stype, cmtypes[st].srcfmt, cmtypes[st].sfunc);
  4463. }
  4464. p.lastSelectedData = query.select();
  4465. var recordsperpage = parseInt(p.rowNum, 10),
  4466. total = p.lastSelectedData.length,
  4467. page = parseInt(p.page, 10),
  4468. totalpages = Math.ceil(total / recordsperpage),
  4469. retresult = {};
  4470. if (p.grouping && p.groupingView._locgr) {
  4471. p.groupingView.groups = [];
  4472. var j, key, udc;
  4473. if (p.footerrow && p.userDataOnFooter) {
  4474. for (key in p.userData) {
  4475. if (p.userData.hasOwnProperty(key)) {
  4476. p.userData[key] = 0;
  4477. }
  4478. }
  4479. udc = true;
  4480. }
  4481. for (j = 0; j < total; j++) {
  4482. if (udc) {
  4483. for (key in p.userData) {
  4484. if (p.userData.hasOwnProperty(key)) {
  4485. p.userData[key] += parseFloat(p.lastSelectedData[j][key] || 0);
  4486. }
  4487. }
  4488. }
  4489. $j.groupingPrepare.call($self, p.lastSelectedData[j], j, recordsperpage);
  4490. }
  4491. }
  4492. query = null;
  4493. cmtypes = null;
  4494. var localReader = p.localReader;
  4495. retresult[localReader.total] = totalpages;
  4496. retresult[localReader.page] = page;
  4497. retresult[localReader.records] = total;
  4498. retresult[localReader.root] = p.lastSelectedData.slice((page - 1) * recordsperpage, page * recordsperpage);
  4499. retresult[localReader.userdata] = p.userData;
  4500. return retresult;
  4501. },
  4502. setWidthOfPagerTdWithPager = function ($pgTable) {
  4503. var self = this, width = $pgTable.outerWidth(), fontSize;
  4504. if (width <= 0) { // not visible
  4505. fontSize = $(self).closest(".ui-jqgrid>.ui-jqgrid-view").css("font-size") || "11px";
  4506. $(document.body).append("<div id='testpg' class='" + getGuiStyles("gBox", "ui-jqgrid") + "' style='font-size:" +
  4507. fontSize +
  4508. ";visibility:hidden;margin:0;padding:0;' ></div>");
  4509. $($pgTable).clone().appendTo("#testpg");
  4510. width = $("#testpg>.ui-pg-table").width();
  4511. $("#testpg").remove();
  4512. }
  4513. if (width > 0) {
  4514. $pgTable.parent().width(width);
  4515. }
  4516. return width;
  4517. },
  4518. updatepager = function (rn, dnd) {
  4519. var self = this, $self = $(self), gridSelf = self.grid, cp, last, base1, from, to, tot, fmt, pgboxes = p.pager || "", sppg,
  4520. tspg = p.pager ? "_" + p.pager.substr(1) : "", bDiv = gridSelf.bDiv, numberFormat = $.fmatter ? $.fmatter.NumberFormat : null,
  4521. tspgTop = p.toppager ? "_" + p.toppager.substr(1) : "",
  4522. hoverClasses = getGuiStyles("states.hover"), disabledClasses = getGuiStyles("states.disabled");
  4523. base1 = parseInt(p.page, 10) - 1;
  4524. if (base1 < 0) { base1 = 0; }
  4525. base1 = base1 * parseInt(p.rowNum, 10);
  4526. to = base1 + p.reccount;
  4527. if (p.scroll) {
  4528. var rows = $(getGridComponent(COMPONENT_NAMES.BODY_TABLE, bDiv)[0].rows).slice(1);//$("tbody:first > tr:gt(0)", bDiv);
  4529. base1 = to - rows.length;
  4530. p.reccount = rows.length;
  4531. var rh = rows.outerHeight() || gridSelf.prevRowHeight;
  4532. if (rh) {
  4533. var top = base1 * rh;
  4534. var height = jgrid.fixMaxHeightOfDiv.call(self, parseInt(p.records, 10) * rh);
  4535. $(bDiv).children("div").first().css({ height: height + "px" })
  4536. .children("div").first().css({ height: top + "px", display: top + "px" ? "" : "none" });
  4537. if (bDiv.scrollTop === 0 && p.page > 1) {
  4538. bDiv.scrollTop = p.rowNum * (p.page - 1) * rh;
  4539. }
  4540. }
  4541. bDiv.scrollLeft = gridSelf.hDiv.scrollLeft;
  4542. }
  4543. pgboxes += p.toppager ? (pgboxes ? "," : "") + p.toppager : "";
  4544. if (pgboxes) {
  4545. fmt = getRes("formatter.integer") || {};
  4546. cp = intNum(p.page);
  4547. last = intNum(p.lastpage);
  4548. $(".selbox", pgboxes).prop("disabled", false);
  4549. if (p.pginput === true) {
  4550. var $pagerInputs = $(".ui-pg-input", pgboxes),
  4551. numberOfDigitsInPageNumber = String(p.page).length;
  4552. $pagerInputs.val(p.page);
  4553. // verify the value of size attribute of "input.ui-pg-input"
  4554. // and increase it if it's required.
  4555. $pagerInputs.each(function () {
  4556. var size = parseInt($(this).attr("size"), 10);
  4557. if (size > 0 && size < numberOfDigitsInPageNumber) {
  4558. $(this).attr("size", numberOfDigitsInPageNumber);
  4559. }
  4560. });
  4561. sppg = p.toppager ? "#sp_1" + tspg + ",#sp_1" + tspgTop : "#sp_1" + tspg;
  4562. $(sppg).html($.fmatter ? numberFormat(p.lastpage, fmt) : p.lastpage)
  4563. .closest(".ui-pg-table").each(function () {
  4564. setWidthOfPagerTdWithPager.call(self, $(this));
  4565. });
  4566. }
  4567. if (p.viewrecords) {
  4568. if (p.reccount === 0) {
  4569. $(".ui-paging-info", pgboxes).html(getDef("emptyrecords"));
  4570. } else {
  4571. from = base1 + 1;
  4572. tot = p.records;
  4573. if ($.fmatter) {
  4574. from = numberFormat(from, fmt);
  4575. to = numberFormat(to, fmt);
  4576. tot = numberFormat(tot, fmt);
  4577. }
  4578. $(".ui-paging-info", pgboxes).html(jgrid.format(getDef("recordtext"), from, to, tot));
  4579. }
  4580. }
  4581. if (p.pgbuttons === true) {
  4582. if (last <= 0) { cp = 0;}
  4583. if (cp <= 0) { cp = last = 0; }
  4584. if (cp === 1 || cp === 0) {
  4585. $("#first" + tspg + ", #prev" + tspg).addClass(disabledClasses).removeClass(hoverClasses);
  4586. if (p.toppager) { $("#first_t" + tspgTop + ", #prev_t" + tspgTop).addClass(disabledClasses).removeClass(hoverClasses); }
  4587. } else {
  4588. $("#first" + tspg + ", #prev" + tspg).removeClass(disabledClasses);
  4589. if (p.toppager) { $("#first_t" + tspgTop + ", #prev_t" + tspgTop).removeClass(disabledClasses); }
  4590. }
  4591. if (cp === last || cp === 0) {
  4592. $("#next" + tspg + ", #last" + tspg).addClass(disabledClasses).removeClass(hoverClasses);
  4593. if (p.toppager) { $("#next_t" + tspgTop + ", #last_t" + tspgTop).addClass(disabledClasses).removeClass(hoverClasses); }
  4594. } else {
  4595. $("#next" + tspg + ", #last" + tspg).removeClass(disabledClasses);
  4596. if (p.toppager) { $("#next_t" + tspgTop + ", #last_t" + tspgTop).removeClass(disabledClasses); }
  4597. }
  4598. }
  4599. }
  4600. if (rn === true && p.rownumbers === true) {
  4601. $(">td.jqgrid-rownum", self.rows).each(function (i) {
  4602. $(this).html(base1 + 1 + i);
  4603. });
  4604. }
  4605. if (dnd && p.jqgdnd) { $self.jqGrid("gridDnD", "updateDnD"); }
  4606. feedback.call(self, "gridComplete");
  4607. $self.triggerHandler("jqGridAfterGridComplete");
  4608. },
  4609. beginReq = function () {
  4610. var self = this;
  4611. self.grid.hDiv.loading = true;
  4612. if (p.hiddengrid) { return; }
  4613. $j.progressBar.call($(self), { method: "show", loadtype: p.loadui, htmlcontent: getDef("loadtext") });
  4614. },
  4615. endReq = function () {
  4616. var self = this;
  4617. self.grid.hDiv.loading = false;
  4618. $j.progressBar.call($(self), { method: "hide", loadtype: p.loadui });
  4619. },
  4620. populate = function (npage) {
  4621. var self = this, $self = $(self), gridSelf = self.grid;
  4622. if (!gridSelf.hDiv.loading) {
  4623. var pvis = p.scroll && npage === false, prm = {}, dt, dstr, pN = p.prmNames;
  4624. if (p.page <= 0) { p.page = Math.min(1, p.lastpage); }
  4625. if (pN.search !== null) { prm[pN.search] = p.search; }
  4626. if (pN.nd !== null) { prm[pN.nd] = new Date().getTime(); }
  4627. if (isNaN(parseInt(p.rowNum, 10)) || parseInt(p.rowNum, 10) <= 0) { p.rowNum = p.maxRowNum; }
  4628. if (pN.rows !== null) { prm[pN.rows] = p.rowNum; }
  4629. if (pN.page !== null) { prm[pN.page] = p.page; }
  4630. if (pN.sort !== null) { prm[pN.sort] = p.sortname; }
  4631. if (pN.order !== null) { prm[pN.order] = p.sortorder; }
  4632. if (p.rowTotal !== null && pN.totalrows !== null) { prm[pN.totalrows] = p.rowTotal; }
  4633. var lcf = isFunction(p.loadComplete), lc = lcf ? p.loadComplete : null;
  4634. var adjust = 0;
  4635. npage = npage || 1;
  4636. if (npage > 1) {
  4637. if (pN.npage !== null) {
  4638. prm[pN.npage] = npage;
  4639. adjust = npage - 1;
  4640. npage = 1;
  4641. } else {
  4642. lc = function (data) {
  4643. p.page++;
  4644. gridSelf.hDiv.loading = false;
  4645. if (lcf) {
  4646. p.loadComplete.call(self, data);
  4647. }
  4648. populate.call(self, npage - 1);
  4649. };
  4650. }
  4651. } else if (pN.npage !== null) {
  4652. delete p.postData[pN.npage];
  4653. }
  4654. if (p.grouping && $j.groupingSetup) {
  4655. $j.groupingSetup.call($self);
  4656. var grp = p.groupingView, gi, gs = "", index, iColumn, cmValue;
  4657. for (gi = 0; gi < grp.groupField.length; gi++) {
  4658. index = grp.groupField[gi];
  4659. for (iColumn = 0; iColumn < p.colModel.length; iColumn++) {
  4660. cmValue = p.colModel[iColumn];
  4661. if (cmValue.name === index && cmValue.index) {
  4662. index = cmValue.index;
  4663. }
  4664. }
  4665. gs += index + " " + grp.groupOrder[gi] + ", ";
  4666. }
  4667. prm[pN.sort] = gs + prm[pN.sort];
  4668. }
  4669. extend(p.postData, prm);
  4670. var rcnt = !p.scroll ? 1 : self.rows.length - 1,
  4671. fixDisplayingHorizontalScrollbar = function () {
  4672. fixScrollOffsetAndhBoxPadding.call(self);
  4673. // if no items are displayed in the btable, but the column header is too wide
  4674. // the horizontal scrollbar of bDiv will be disabled.
  4675. if (!p.autowidth && (p.widthOrg === undefined || p.widthOrg === "auto" || p.widthOrg === "100%")) {
  4676. $j.setGridWidth.call($self, p.tblwidth + p.scrollOffset, false);
  4677. }
  4678. },
  4679. resort = function () {
  4680. var iRes;
  4681. if (p.autoresizeOnLoad) {
  4682. $j.autoResizeAllColumns.call($self);
  4683. clearArray(p.columnsToReResizing);
  4684. if (p.autowidth) {
  4685. $j.setGridWidth.call($self,
  4686. $self.closest(".ui-jqgrid").parent().width(),
  4687. true);
  4688. }
  4689. } else {
  4690. for (iRes = 0; iRes < p.columnsToReResizing.length; iRes++) {
  4691. $j.autoResizeColumn.call($self, p.columnsToReResizing[iRes]);
  4692. }
  4693. clearArray(p.columnsToReResizing);
  4694. }
  4695. },
  4696. finalReportSteps = function () {
  4697. feedback.call(self, "loadComplete", dstr);
  4698. resort();
  4699. $self.triggerHandler("jqGridAfterLoadComplete", [dstr]);
  4700. endReq.call(self);
  4701. p.datatype = "local";
  4702. p.datastr = null;
  4703. fixDisplayingHorizontalScrollbar();
  4704. },
  4705. finalReportVirtual = function (data) {
  4706. $self.triggerHandler("jqGridLoadComplete", [data]);
  4707. if (lc) { lc.call(self, data); }
  4708. resort();
  4709. $self.triggerHandler("jqGridAfterLoadComplete", [data]);
  4710. if (pvis) { gridSelf.populateVisible.call(self); }
  4711. if (npage === 1) { endReq.call(self); }
  4712. fixDisplayingHorizontalScrollbar();
  4713. },
  4714. readLocal = function () {
  4715. var req = addLocalData.call(self);
  4716. readInput.call(self, req, rcnt, npage > 1, adjust);
  4717. finalReportVirtual(req);
  4718. };
  4719. if (!feedback.call(self, "beforeRequest")) { return; }
  4720. if (isFunction(p.datatype)) { p.datatype.call(self, p.postData, "load_" + p.id, rcnt, npage, adjust); return; }
  4721. dt = p.datatype.toLowerCase();
  4722. $(grid.eDiv).hide();
  4723. switch (dt) {
  4724. case "json":
  4725. case "jsonp":
  4726. case "xml":
  4727. case "script":
  4728. $.ajax(extend({
  4729. url: p.url,
  4730. type: p.mtype,
  4731. dataType: dt,
  4732. //data: $.isFunction(p.serializeGridData)? p.serializeGridData.call(self,p.postData) : p.postData,
  4733. data: jgrid.serializeFeedback.call(ts, p.serializeGridData, "jqGridSerializeGridData", p.postData),
  4734. success: function (data, textStatus, jqXHR) {
  4735. p.jqXhr = null;
  4736. $(grid.eDiv).hide();
  4737. if (isFunction(p.beforeProcessing)) {
  4738. if (p.beforeProcessing.call(self, data, textStatus, jqXHR) === false) {
  4739. endReq.call(self);
  4740. return;
  4741. }
  4742. }
  4743. readInput.call(self, data, rcnt, npage > 1, adjust);
  4744. finalReportVirtual(data);
  4745. if (p.loadonce || p.treeGrid) {
  4746. p.dataTypeOrg = p.datatype;
  4747. p.datatype = "local";
  4748. if (p.forceClientSorting) { readLocal(); }
  4749. }
  4750. },
  4751. error: function (jqXHR, textStatus, errorThrown) {
  4752. p.jqXhr = null;
  4753. if (isFunction(p.loadError)) { p.loadError.call(self, jqXHR, textStatus, errorThrown); }
  4754. if (npage === 1) { endReq.call(self); }
  4755. },
  4756. beforeSend: function (jqXHR, settings) {
  4757. var gotoreq = true;
  4758. if (isFunction(p.loadBeforeSend)) {
  4759. gotoreq = p.loadBeforeSend.call(self, jqXHR, settings);
  4760. }
  4761. if (gotoreq === undefined) { gotoreq = true; }
  4762. if (gotoreq === false) {
  4763. return false;
  4764. }
  4765. p.jqXhr = jqXHR;
  4766. beginReq.call(self);
  4767. }
  4768. }, jgrid.ajaxOptions, p.ajaxGridOptions));
  4769. break;
  4770. case "xmlstring":
  4771. beginReq.call(self);
  4772. dstr = typeof p.datastr === "string" ? $.parseXML(p.datastr) : p.datastr;
  4773. readInput.call(self, dstr);
  4774. finalReportSteps();
  4775. if (p.forceClientSorting) { readLocal(); }
  4776. break;
  4777. case "jsonstring":
  4778. beginReq.call(self);
  4779. dstr = p.datastr && typeof p.datastr === "string" ? $.parseJSON(p.datastr) : p.datastr;
  4780. readInput.call(self, dstr);
  4781. finalReportSteps();
  4782. if (p.forceClientSorting) { readLocal(); }
  4783. break;
  4784. case "local":
  4785. case "clientside":
  4786. beginReq.call(self);
  4787. p.datatype = "local";
  4788. readLocal();
  4789. break;
  4790. }
  4791. }
  4792. },
  4793. setHeadCheckBox = function (checked) {
  4794. var self = this, gridSelf = self.grid;
  4795. $(p.cb, gridSelf.hDiv).prop("checked", checked);
  4796. if (p.frozenColumns) {
  4797. $(p.cb, gridSelf.fhDiv).prop("checked", checked);
  4798. }
  4799. },
  4800. cancelOrSaveEditing = function (mode) {
  4801. // The current code don't take in the consideration errors during
  4802. // remote saving/canceling. The standard behavior in case of
  4803. // remote saving/canceling is wating till the server response and
  4804. // holding inline/cell editing if saving/canceling failed by some
  4805. // server reason. The current code of cancelOrSaveEditing
  4806. // don't wait for the server response
  4807. var iEditing, savedRowInfo;
  4808. for (iEditing = 0; iEditing < p.savedRow.length; iEditing++) {
  4809. savedRowInfo = p.savedRow[iEditing];
  4810. if (mode === "save") {
  4811. if (savedRowInfo.hasOwnProperty("ic")) {
  4812. $self0.jqGrid("saveCell", savedRowInfo.id, savedRowInfo.ic);
  4813. } else {
  4814. $self0.jqGrid("saveRow", savedRowInfo.id);
  4815. }
  4816. } else {
  4817. // mode === "cancel"
  4818. if (savedRowInfo.hasOwnProperty("ic")) {
  4819. $self0.jqGrid("restoreCell", savedRowInfo.id, savedRowInfo.ic);
  4820. } else {
  4821. $self0.jqGrid("restoreRow", savedRowInfo.id);
  4822. }
  4823. }
  4824. }
  4825. //clearArray(p.savedRow); // p.savedRow = [];
  4826. //p.editingInfo = {};
  4827. },
  4828. setPager = function (pgid, tp) {
  4829. var hoverClasses = getGuiStyles("states.hover"), disabledClasses = getGuiStyles("states.disabled"),
  4830. sep = "<td class='ui-pg-button " + disabledClasses + "'><span class='ui-separator'></span></td>",
  4831. pginp = "",
  4832. blockAlign = p.pagerpos === "left" ? "margin-right:auto;" : (p.pagerpos === "right" ? "margin-left:auto;" : "margin-left:auto;margin-right:auto;"),
  4833. pgl = "<table " + "style='table-layout:auto;white-space: pre;" + blockAlign + "' class='ui-pg-table'><tbody><tr>",
  4834. str = "", pgcnt, lft, cent, rgt, twd, i,
  4835. clearVals = function (onpaging, newPage, newRowNum) {
  4836. if (p.savedRow.length > 0 && p.pagingDuringEditing === "prevent") {
  4837. return false;
  4838. }
  4839. if (!feedback.call(ts, "onPaging", onpaging, {
  4840. newPage: newPage,
  4841. currentPage: intNum(p.page, 1),
  4842. lastPage: intNum(p.lastpage, 1),
  4843. currentRowNum: intNum(p.rowNum, 10),
  4844. newRowNum: newRowNum
  4845. })) {
  4846. return false;
  4847. }
  4848. p.selrow = null;
  4849. if (p.multiselect) {
  4850. if (!p.multiPageSelection) {
  4851. clearArray(p.selarrrow); // p.selarrrow = [];
  4852. }
  4853. setHeadCheckBox.call(ts, false);
  4854. }
  4855. cancelOrSaveEditing(p.pagingDuringEditing);
  4856. return true;
  4857. };
  4858. tp += "_" + pgid;
  4859. pgcnt = "pg_" + pgid;
  4860. lft = pgid + "_left";
  4861. cent = pgid + "_center";
  4862. rgt = pgid + "_right";
  4863. $("#" + jqID(pgid))
  4864. .append("<div id='" + pgcnt + "' class='ui-pager-control' role='group'><table class='ui-pg-table' style='width:100%;table-layout:fixed;height:100%;'><tbody><tr>" +
  4865. "<td id='" + lft + "' class='ui-jqgrid-pg-left'" + (p.pagerLeftWidth !== undefined ? " style='width:" + p.pagerLeftWidth + "px;'" : "") + "></td>" +
  4866. "<td id='" + cent + "' class='ui-jqgrid-pg-center'" + (p.pagerCenterWidth !== undefined ? " style='width:" + p.pagerCenterWidth + "px;'" : "") + "></td>" +
  4867. "<td id='" + rgt + "' class='ui-jqgrid-pg-right'" + (p.pagerRightWidth !== undefined ? " style='width:" + p.pagerRightWidth + "px;'" : "") + "></td></tr></tbody></table></div>")
  4868. .attr("dir", "ltr"); //explicit setting
  4869. pgcnt = "#" + jqID(pgcnt); // modify to id selector
  4870. if (p.rowList.length > 0) {
  4871. str = "<td dir='" + dir + "'>";
  4872. var pgrecs = getDef("pgrecs");
  4873. str += "<select class='" + getGuiStyles("pager.pagerSelect", "ui-pg-selbox") + "' " + (pgrecs ? "title='" + pgrecs + "'" : "") + ">";
  4874. var strnm;
  4875. for (i = 0; i < p.rowList.length; i++) {
  4876. strnm = p.rowList[i].toString().split(":");
  4877. if (strnm.length === 1) {
  4878. strnm[1] = strnm[0];
  4879. }
  4880. str += "<option value='" + strnm[0] + "'" + ((intNum(p.rowNum, 0) === intNum(strnm[0], 0)) ? " selected='selected'" : "") + ">" + strnm[1] + "</option>";
  4881. }
  4882. str += "</select></td>";
  4883. }
  4884. if (dir === "rtl") { pgl += str; }
  4885. if (p.pginput === true) { pginp = "<td dir='" + dir + "'>" + jgrid.format(getDef("pgtext") || "", "<input aria-label='Page No.' class='" + getGuiStyles("pager.pagerInput", "ui-pg-input") + "' type='text' size='2' maxlength='7' value='0'/>", "<span id='sp_1_" + pgid + "'>0</span>") + "</td>"; }
  4886. pgid = "#" + jqID(pgid); // modify to id selector
  4887. if (p.pgbuttons === true) {
  4888. var po = ["first", "prev", "next", "last"],
  4889. poIcons = po.slice(),
  4890. buttonClasses = getGuiStyles("pager.pagerButton", "ui-pg-button"),
  4891. buildPagerButton = function (buttonName, iconName) {
  4892. var titleText = getDef("pg" + buttonName);
  4893. return "<td role='button' tabindex='0' id='" + buttonName + tp + "' class='" + buttonClasses + "' " +
  4894. (titleText ? "title='" + titleText + "'" : "") + "><span class='" + getIcon("pager." + iconName) + "'></span></td>";
  4895. };
  4896. if (dir === "rtl") { po.reverse(); }
  4897. for (i = 0; i < po.length; i++) {
  4898. pgl += buildPagerButton(po[i], poIcons[i]);
  4899. if (i === 1) {
  4900. pgl += pginp !== "" ? sep + pginp + sep : "";
  4901. }
  4902. }
  4903. } else if (pginp !== "") { pgl += pginp; }
  4904. if (dir === "ltr") { pgl += str; }
  4905. pgl += "</tr></tbody></table>";
  4906. if (p.viewrecords === true) { $("td" + pgid + "_" + p.recordpos, pgcnt).append("<span dir='" + dir + "' style='text-align:" + p.recordpos + "' class='ui-paging-info'></span>"); }
  4907. var $pagerIn = $("td" + pgid + "_" + p.pagerpos, pgcnt);
  4908. $pagerIn.append(pgl);
  4909. twd = setWidthOfPagerTdWithPager.call(this, $pagerIn.children(".ui-pg-table"));
  4910. p._nvtd = [];
  4911. p._nvtd[0] = twd ? Math.floor((p.width - twd) / 2) : Math.floor(p.width / 3);
  4912. p._nvtd[1] = 0;
  4913. pgl = null;
  4914. $(".ui-pg-selbox", pgcnt).on("change", function () {
  4915. var newRowNum = intNum(this.value, 10),
  4916. newPage = Math.round(p.rowNum * (p.page - 1) / newRowNum - 0.5) + 1;
  4917. if (!clearVals("records", newPage, newRowNum)) { return false; }
  4918. p.page = newPage;
  4919. p.rowNum = newRowNum;
  4920. if (p.pager) { $(".ui-pg-selbox", p.pager).val(newRowNum); }
  4921. if (p.toppager) { $(".ui-pg-selbox", p.toppager).val(newRowNum); }
  4922. populate.call(ts);
  4923. return false;
  4924. });
  4925. if (p.pgbuttons === true) {
  4926. $(".ui-pg-button", pgcnt).hover(function () {
  4927. if (hasOneFromClasses(this, disabledClasses)) {
  4928. this.style.cursor = "default";
  4929. } else {
  4930. $(this).addClass(hoverClasses);
  4931. this.style.cursor = "pointer";
  4932. }
  4933. }, function () {
  4934. if (!hasOneFromClasses(this, disabledClasses)) {
  4935. $(this).removeClass(hoverClasses);
  4936. this.style.cursor = "default";
  4937. }
  4938. });
  4939. $("#first" + jqID(tp) + ", #prev" + jqID(tp) + ", #next" + jqID(tp) + ", #last" + jqID(tp)).click(function () {
  4940. if (hasOneFromClasses(this, disabledClasses)) {
  4941. return false;
  4942. }
  4943. var cp = intNum(p.page, 1), newPage = cp, onpaging = this.id,
  4944. last = intNum(p.lastpage, 1), selclick = false,
  4945. fp = true, pp = true, np = true, lp = true;
  4946. if (last === 0 || last === 1) {
  4947. if (cp <= 1) {
  4948. fp = false;
  4949. pp = false;
  4950. }
  4951. np = false;
  4952. lp = false;
  4953. } else if (last > 1 && cp >= 1) {
  4954. if (cp === 1) {
  4955. fp = false;
  4956. pp = false;
  4957. } else if (cp === last) {
  4958. np = false;
  4959. lp = false;
  4960. }
  4961. } else if (last > 1 && cp === 0) {
  4962. np = false;
  4963. lp = false;
  4964. cp = last - 1;
  4965. }
  4966. if (this.id === "first" + tp && fp) {
  4967. onpaging = "first";
  4968. newPage = 1;
  4969. selclick = true;
  4970. }
  4971. if (this.id === "prev" + tp && pp) {
  4972. onpaging = "prev";
  4973. newPage = (cp - 1);
  4974. selclick = true;
  4975. }
  4976. if (this.id === "next" + tp && np) {
  4977. onpaging = "next";
  4978. newPage = (cp + 1);
  4979. selclick = true;
  4980. }
  4981. if (this.id === "last" + tp && lp) {
  4982. onpaging = "last";
  4983. newPage = last;
  4984. selclick = true;
  4985. }
  4986. if (!clearVals(onpaging, newPage, intNum(p.rowNum, 10))) { return false; }
  4987. p.page = newPage;
  4988. if (selclick) {
  4989. populate.call(ts);
  4990. }
  4991. return false;
  4992. });
  4993. }
  4994. if (p.pginput === true) {
  4995. $("input.ui-pg-input", pgcnt).on("keypress.jqGrid", function (e) {
  4996. var key = e.charCode || e.keyCode || 0, newPage = intNum($(this).val(), 1);
  4997. if (key === 13) {
  4998. if (!clearVals("user", newPage, intNum(p.rowNum, 10))) { return false; }
  4999. $(this).val(newPage);
  5000. p.page = ($(this).val() > 0) ? $(this).val() : p.page;
  5001. populate.call(ts);
  5002. return false;
  5003. }
  5004. return this;
  5005. });
  5006. }
  5007. $pagerIn.children(".ui-pg-table").on("keydown.jqGrid", function (e) {
  5008. var $focused;
  5009. if (e.which === 13) {
  5010. $focused = $pagerIn.find(":focus");
  5011. if ($focused.length > 0) {
  5012. $focused.trigger("click");
  5013. }
  5014. }
  5015. });
  5016. },
  5017. getSortNames = function (sortNames, sortDirs, cm) {
  5018. // sortNames, sortDirs MUST be initialized to [] and {} before
  5019. // process sortname
  5020. each((p.sortname + " " + p.sortorder).split(","), function () {
  5021. var s = $.trim(this).split(" ");
  5022. if (s.length === 2) {
  5023. sortNames.push(s[0]);
  5024. }
  5025. });
  5026. if (cm != null) {
  5027. var i = $.inArray(cm.index || cm.name, sortNames);
  5028. if (cm.lso !== "" && i < 0) {
  5029. // new column is clicked
  5030. sortNames.push(cm.index || cm.name);
  5031. } else if (cm.lso === "" && i >= 0) {
  5032. // remove column
  5033. sortNames.splice(i, 1);
  5034. }
  5035. }
  5036. each(p.colModel, function () {
  5037. var sortName = this.index || this.name, splas;
  5038. if (this.lso) {
  5039. splas = this.lso.split("-");
  5040. if ($.inArray(sortName, sortNames) < 0) {
  5041. sortNames.push(sortName);
  5042. }
  5043. sortDirs[sortName] = splas[splas.length - 1];
  5044. }
  5045. });
  5046. },
  5047. multiSort = function (iCol1, obj) {
  5048. var sort1 = "", cm = p.colModel[iCol1], so,
  5049. disabledClasses = getGuiStyles("states.disabled"),
  5050. $selTh = p.frozenColumns ? $(ts.grid.headers[iCol1].el).add($(obj)) : $(ts.grid.headers[iCol1].el),
  5051. $iconsSpan = $selTh.find("span.s-ico"),
  5052. $iconAsc = $iconsSpan.children("span.ui-icon-asc"),
  5053. $iconDesc = $iconsSpan.children("span.ui-icon-desc"),
  5054. $iconsActive = $iconAsc, $iconsInictive = $iconDesc, sortNames = [], sortDirs = {};
  5055. $selTh.find("span.ui-grid-ico-sort").addClass(disabledClasses); // for both icons
  5056. $selTh.attr("aria-selected", "false");
  5057. if (cm.lso) {
  5058. $iconsSpan.show();
  5059. so = cm.lso.split("-");
  5060. so = so[so.length - 1];
  5061. if (so === "desc") {
  5062. $iconsActive = $iconDesc;
  5063. $iconsInictive = $iconAsc;
  5064. }
  5065. $iconsActive.removeClass(disabledClasses).css("display", ""); // show;
  5066. if (p.showOneSortIcon) {
  5067. $iconsInictive.hide();
  5068. }
  5069. $selTh.attr("aria-selected", "true");
  5070. } else if (!p.viewsortcols[0]) {
  5071. $iconsSpan.hide();
  5072. }
  5073. getSortNames(sortNames, sortDirs, cm);
  5074. if (typeof p.sortname === "string" && p.sortname !== "" && p.sortname.split(",").length < sortNames.length) {
  5075. var removeSorting = function (sortNameToRemove) {
  5076. each(p.colModel, function () {
  5077. var indexInSortNames, thDivIdSelector = "#jqgh_" + jgrid.jqID(p.id + "_" + this.name),
  5078. $thDiv = $(thDivIdSelector);
  5079. if (this.lso && (this.index || this.name) === sortNameToRemove) {
  5080. if (typeof sortNames.indexOf === "function") {
  5081. indexInSortNames = sortNames.indexOf(sortNameToRemove);
  5082. } else {
  5083. // old web browser
  5084. for (indexInSortNames = 0; indexInSortNames < sortNames.length; indexInSortNames++) {
  5085. if (sortNames[indexInSortNames] === sortNameToRemove) {
  5086. break;
  5087. }
  5088. }
  5089. if (indexInSortNames === sortNames.length) {
  5090. indexInSortNames = -1;
  5091. }
  5092. }
  5093. if (indexInSortNames >= 0) {
  5094. sortNames.splice(indexInSortNames, 1);
  5095. this.lso = "";
  5096. }
  5097. }
  5098. if (p.frozenColumns) {
  5099. $thDiv = $thDiv.add($(grid.fhDiv).find(thDivIdSelector));
  5100. }
  5101. $thDiv.children(".s-ico")[this.lso ? "show" : "hide"]();
  5102. });
  5103. };
  5104. if (p.multiSortOrder === "lastClickedFirstSorted" && sortNames.length > 1) {
  5105. sortNames.unshift(sortNames[sortNames.length - 1]);
  5106. sortNames.pop();
  5107. while (sortNames.length > p.maxSortColumns) {
  5108. removeSorting(sortNames[sortNames.length - 1]); //sortNames.pop() and a little more
  5109. }
  5110. } else if (isFunction(p.multiSortOrder)) {
  5111. sortNames = p.multiSortOrder.call(ts, {
  5112. sortNames: sortNames,
  5113. cm: cm,
  5114. sortDirs: sortDirs,
  5115. removeSorting: removeSorting
  5116. }) || sortNames;
  5117. }
  5118. }
  5119. each(sortNames, function () {
  5120. if (sort1.length > 0) { sort1 += ", "; }
  5121. sort1 += this + " " + sortDirs[this];
  5122. p.sortorder = sortDirs[this];
  5123. });
  5124. p.sortname = sort1.substring(0, sort1.length - p.sortorder.length - 1);
  5125. if (p.showSortOrder) {
  5126. // reset multisort indexes
  5127. each(p.colModel, function () {
  5128. if (this.sortable) {
  5129. var sortIndex = inArray(this.name, sortNames),
  5130. thDivIdSelector = "#jqgh_" + jgrid.jqID(p.id + "_" + this.name),
  5131. $thDiv = $(thDivIdSelector);
  5132. if (p.frozenColumns) {
  5133. $thDiv = $thDiv.add($(grid.fhDiv).find(thDivIdSelector));
  5134. }
  5135. $thDiv
  5136. .children(".ui-jqgrid-sort-order")
  5137. .html(sortIndex < 0 ?
  5138. "&nbsp;" :
  5139. isFunction(p.formatSortOrder) ?
  5140. p.formatSortOrder.call(ts, { cm: this, sortIndex: sortIndex }) :
  5141. sortIndex + 1);
  5142. }
  5143. });
  5144. }
  5145. },
  5146. sortData = function (index, idxcol, reload, sor, obj, e) {
  5147. var self = this, mygrid = self.grid, cm = p.colModel[idxcol], disabledClasses = getGuiStyles("states.disabled");
  5148. if (cm == null || !cm.sortable) { return; }
  5149. if (p.savedRow.length > 0 && p.sortingDuringEditing === "prevent") { return; }
  5150. if (p.lastsort === idxcol && p.sortname !== "") {
  5151. if (p.sortorder === "asc") {
  5152. p.sortorder = "desc";
  5153. } else if (p.sortorder === "desc") {
  5154. p.sortorder = "asc";
  5155. } else {
  5156. p.sortorder = cm.firstsortorder || "asc";
  5157. }
  5158. } else {
  5159. p.sortorder = cm.firstsortorder || "asc";
  5160. }
  5161. // first set new value of lso:
  5162. // "asc" -> "asc-desc", new sorting to "desc"
  5163. // "desc" -> "desc-asc", new sorting to "asc"
  5164. // "asc-desc" or "desc-asc" -> "", no new sorting ""
  5165. // "" -> cm.firstsortorder || "asc"
  5166. if (cm.lso) {
  5167. if (cm.lso === "asc") {
  5168. cm.lso += "-desc";
  5169. } else if (cm.lso === "desc") {
  5170. cm.lso += "-asc";
  5171. } else if ((cm.lso === "asc-desc" || cm.lso === "desc-asc") && (p.threeStateSort || p.multiSort)) {
  5172. cm.lso = "";
  5173. }
  5174. } else {
  5175. cm.lso = cm.firstsortorder || "asc";
  5176. }
  5177. if (!reload && p.resetPageAfterSort) {
  5178. p.page = 1;
  5179. }
  5180. if (p.multiSort) {
  5181. multiSort(idxcol, obj);
  5182. } else {
  5183. if (sor) {
  5184. if (p.lastsort === idxcol && p.sortorder === sor && !reload) { return; }
  5185. p.sortorder = sor;
  5186. }
  5187. var headers = mygrid.headers, fhDiv = mygrid.fhDiv,
  5188. $previousSelectedTh = headers[p.lastsort] ? $(headers[p.lastsort].el) : $(),
  5189. $newSelectedTh = p.frozenColumns ? $(obj) : $(headers[idxcol].el),
  5190. $iconsSpan = $newSelectedTh.find("span.s-ico"),
  5191. $iconsActive = $iconsSpan.children(".ui-icon-" + p.sortorder),
  5192. $iconsInictive = $iconsSpan.children(".ui-icon-" + (p.sortorder === "asc" ? "desc" : "asc"));
  5193. cm = p.colModel[p.lastsort];
  5194. $previousSelectedTh.find(".ui-grid-ico-sort").addClass(disabledClasses);
  5195. $previousSelectedTh.attr("aria-selected", "false");
  5196. if (p.frozenColumns) {
  5197. fhDiv.find(".ui-grid-ico-sort").addClass(disabledClasses);
  5198. fhDiv.find("th").attr("aria-selected", "false");
  5199. }
  5200. if (!p.viewsortcols[0]) {
  5201. if (p.lastsort !== idxcol) {
  5202. if (p.frozenColumns) {
  5203. fhDiv.find("span.s-ico").hide();
  5204. }
  5205. $previousSelectedTh.find("span.s-ico").hide();
  5206. $iconsSpan.show();
  5207. } else if (p.sortname === "") { // if p.lastsort === idxcol but p.sortname === ""
  5208. $iconsSpan.show(); // ???
  5209. }
  5210. }
  5211. if (p.lastsort !== idxcol) {
  5212. if ($previousSelectedTh.data("autoResized") === "true" &&
  5213. ((cm != null && cm.autoResizing != null && cm.autoResizing.compact) ||
  5214. p.autoResizing.compact)) {
  5215. // recalculate the width of the column after removing sort icon
  5216. p.columnsToReResizing.push(p.lastsort);
  5217. }
  5218. }
  5219. cm = p.colModel[idxcol];
  5220. $iconsSpan.css("display", ""); // show
  5221. if (cm.lso !== "") {
  5222. $iconsActive.removeClass(disabledClasses).css("display", ""); // show
  5223. if (p.showOneSortIcon) {
  5224. $iconsInictive.removeClass(disabledClasses).hide();
  5225. }
  5226. $newSelectedTh.attr("aria-selected", "true");
  5227. } else {
  5228. $newSelectedTh.attr("aria-selected", "false");
  5229. if (p.threeStateSort) {
  5230. p.sortorder = "";
  5231. if (!p.viewsortcols[0]) {
  5232. $iconsSpan.hide();
  5233. }
  5234. }
  5235. }
  5236. if (p.lastsort !== idxcol && $newSelectedTh.data("autoResized") === "true") {
  5237. if ((cm != null && cm.autoResizing != null && cm.autoResizing.compact) ||
  5238. p.autoResizing.compact) {
  5239. // recalculate the width of the column after removing sort icon
  5240. p.columnsToReResizing.push(idxcol);
  5241. }
  5242. }
  5243. p.sortname = cm.index || index;
  5244. }
  5245. if (!feedback.call(self, "onSortCol", p.sortname, idxcol, p.sortorder, e || {})) {
  5246. p.lastsort = idxcol;
  5247. return;
  5248. }
  5249. if (p.datatype === "local") {
  5250. if (p.deselectAfterSort && !p.multiPageSelection) { $j.resetSelection.call($(self)); }
  5251. } else if (!p.multiPageSelection) {
  5252. p.selrow = null;
  5253. if (p.multiselect) {
  5254. setHeadCheckBox.call(self, false);
  5255. clearArray(p.selarrrow); //p.selarrrow =[];
  5256. }
  5257. }
  5258. cancelOrSaveEditing(p.sortingDuringEditing);
  5259. if (p.scroll) {
  5260. var sscroll = mygrid.bDiv.scrollLeft;
  5261. grid.emptyRows.call(self, true, false);
  5262. mygrid.hDiv.scrollLeft = sscroll;
  5263. }
  5264. if (p.subGrid && p.datatype === "local") {
  5265. $("td.sgexpanded", "#" + jqID(p.id)).each(function () {
  5266. $(this).trigger("click");
  5267. });
  5268. }
  5269. populate.call(self);
  5270. p.lastsort = idxcol;
  5271. if (p.sortname !== index && idxcol) { p.lastsort = idxcol; }
  5272. },
  5273. setInitialColWidth = function () {
  5274. var initialWidth = 0, borderAndPaddingWidth = jgrid.cell_width ? 0 : intNum(p.cellLayout, 0), numberOfVariableColumns = 0, iLastVariableColumn, scrollbarWidth = intNum(p.scrollOffset, 0), columnWidth, hasScrollbar = false, totalVariableWidth, fixedColumnsWidth = 0, correctur,
  5275. isCellClassHidden = jgrid.isCellClassHidden;
  5276. each(p.colModel, function () {
  5277. if (this.hidden === undefined) { this.hidden = false; }
  5278. if (p.grouping && p.autowidth) {
  5279. var ind = inArray(this.name, p.groupingView.groupField);
  5280. if (ind >= 0 && p.groupingView.groupColumnShow.length > ind) {
  5281. this.hidden = !p.groupingView.groupColumnShow[ind];
  5282. }
  5283. }
  5284. this.widthOrg = columnWidth = intNum(this.width, 0);
  5285. if (this.hidden === false && !isCellClassHidden(this.classes)) {
  5286. initialWidth += columnWidth + borderAndPaddingWidth;
  5287. if (this.fixed) {
  5288. fixedColumnsWidth += columnWidth + borderAndPaddingWidth;
  5289. } else {
  5290. numberOfVariableColumns++;
  5291. }
  5292. }
  5293. });
  5294. if (isNaN(p.width)) {
  5295. p.width = initialWidth + ((p.shrinkToFit === false && !isNaN(p.height)) ? scrollbarWidth : 0);
  5296. }
  5297. grid.width = p.width;
  5298. p.tblwidth = initialWidth;
  5299. if (p.shrinkToFit === false && p.forceFit === true) { p.forceFit = false; }
  5300. if (p.shrinkToFit === true && numberOfVariableColumns > 0) {
  5301. totalVariableWidth = grid.width - borderAndPaddingWidth * numberOfVariableColumns - fixedColumnsWidth;
  5302. if (!isNaN(p.height)) {
  5303. totalVariableWidth -= scrollbarWidth;
  5304. hasScrollbar = true;
  5305. }
  5306. initialWidth = 0;
  5307. each(p.colModel, function (i) {
  5308. if (this.hidden === false && !isCellClassHidden(this.classes) && !this.fixed) {
  5309. columnWidth = Math.round(totalVariableWidth * this.width / (p.tblwidth - borderAndPaddingWidth * numberOfVariableColumns - fixedColumnsWidth));
  5310. this.width = columnWidth;
  5311. initialWidth += columnWidth;
  5312. iLastVariableColumn = i;
  5313. }
  5314. });
  5315. correctur = 0;
  5316. if (hasScrollbar) {
  5317. if (grid.width - fixedColumnsWidth - (initialWidth + borderAndPaddingWidth * numberOfVariableColumns) !== scrollbarWidth) {
  5318. correctur = grid.width - fixedColumnsWidth - (initialWidth + borderAndPaddingWidth * numberOfVariableColumns) - scrollbarWidth;
  5319. }
  5320. } else if (!hasScrollbar && Math.abs(grid.width - fixedColumnsWidth - (initialWidth + borderAndPaddingWidth * numberOfVariableColumns)) !== 1) {
  5321. correctur = grid.width - fixedColumnsWidth - (initialWidth + borderAndPaddingWidth * numberOfVariableColumns);
  5322. }
  5323. p.colModel[iLastVariableColumn].width += correctur;
  5324. p.tblwidth = initialWidth + correctur + borderAndPaddingWidth * numberOfVariableColumns + fixedColumnsWidth;
  5325. if (p.tblwidth > p.width) {
  5326. p.colModel[iLastVariableColumn].width -= (p.tblwidth - parseInt(p.width, 10));
  5327. p.tblwidth = p.width;
  5328. }
  5329. }
  5330. },
  5331. nextVisible = function (iCol1) {
  5332. var ret = iCol1, j = iCol1, i;
  5333. for (i = iCol1 + 1; i < p.colModel.length; i++) {
  5334. if (p.colModel[i].hidden !== true) {
  5335. j = i;
  5336. break;
  5337. }
  5338. }
  5339. return j - ret;
  5340. },
  5341. getColumnHeaderIndex = function (th) {
  5342. // TODO: adjust the code after adjust the way which generates
  5343. // ids of frozen columns
  5344. return p.iColByName[(th.id || "").substring(p.id.length + 1)];
  5345. },
  5346. colTemplate;
  5347. if (inArray(p.multikey, sortkeys) === -1) { p.multikey = false; }
  5348. p.keyName = false;
  5349. p.sortorder = p.sortorder.toLowerCase();
  5350. jgrid.cell_width = jgrid.cellWidth();
  5351. var jgridCmTemplate = jgrid.cmTemplate, iCol, cmi;
  5352. for (iCol = 0; iCol < p.colModel.length; iCol++) {
  5353. cmi = p.colModel[iCol];
  5354. colTemplate = typeof cmi.template === "string" ?
  5355. (jgridCmTemplate != null && (typeof jgridCmTemplate[cmi.template] === "object" || isFunction(jgridCmTemplate[cmi.template])) ?
  5356. jgridCmTemplate[cmi.template] : {}) :
  5357. cmi.template;
  5358. if (isFunction(colTemplate)) {
  5359. colTemplate = colTemplate.call(ts, { cm: cmi, iCol: iCol });
  5360. }
  5361. cmi = extend(true, {}, p.cmTemplate, colTemplate || {}, cmi);
  5362. if (p.keyName === false && cmi.key === true) {
  5363. p.keyName = cmi.name;
  5364. }
  5365. p.colModel[iCol] = cmi;
  5366. }
  5367. p.indexByColumnData = buildEmptyIndexedColumnMap();
  5368. for (iCol = 0; iCol < p.additionalProperties.length; iCol++) {
  5369. cmi = p.additionalProperties[iCol];
  5370. if (p.keyName === false && cmi.key === true) {
  5371. p.keyName = cmi.name;
  5372. }
  5373. }
  5374. if (p.colNames.length === 0) {
  5375. for (iCol = 0; iCol < p.colModel.length; iCol++) {
  5376. p.colNames[iCol] = p.colModel[iCol].label !== undefined ? p.colModel[iCol].label : p.colModel[iCol].name;
  5377. }
  5378. }
  5379. if (p.colNames.length !== p.colModel.length) {
  5380. fatalErrorFunction(getRes("errors.model"));
  5381. return;
  5382. }
  5383. if (p.grouping === true) {
  5384. p.scroll = false;
  5385. p.rownumbers = false;
  5386. //p.subGrid = false; expiremental
  5387. p.treeGrid = false;
  5388. p.gridview = true;
  5389. }
  5390. if (p.subGrid && isFunction($j.setSubGrid)) {
  5391. try { $j.setSubGrid.call($self0); } catch (ignore1) { }
  5392. }
  5393. if (p.multiselect && (p.multiselectPosition === "left" || p.multiselectPosition === "right")) {
  5394. var insertMethod = p.multiselectPosition === "left" ? "unshift" : "push";
  5395. p.colNames[insertMethod]("<input id='" + p.cbId + "' class='cbox' type='checkbox' aria-checked='false'/>");
  5396. p.colModel[insertMethod]({ name: "cb", width: jgrid.cell_width ? p.multiselectWidth + p.cellLayout : p.multiselectWidth, labelClasses: "jqgh_cbox", classes: "td_cbox", sortable: false, resizable: false, hidedlg: true, search: false, align: "center", fixed: true, frozen: true });
  5397. }
  5398. if (p.rownumbers) {
  5399. p.colNames.unshift("");
  5400. p.colModel.unshift({ name: "rn", width: jgrid.cell_width ? p.rownumWidth + p.cellLayout : p.rownumWidth, labelClasses: "jqgh_rn", sortable: false, resizable: false, hidedlg: true, search: false, align: "center", fixed: true, frozen: true });
  5401. }
  5402. p.iColByName = buildColNameMap(p.colModel);
  5403. p.xmlReader = extend(true, {
  5404. root: "rows",
  5405. row: "row",
  5406. page: "rows>page",
  5407. total: "rows>total",
  5408. records: "rows>records",
  5409. repeatitems: true,
  5410. cell: "cell",
  5411. id: "[id]",
  5412. userdata: "userdata",
  5413. subgrid: { root: "rows", row: "row", repeatitems: true, cell: "cell" }
  5414. }, p.xmlReader);
  5415. p.jsonReader = extend(true, {
  5416. root: "rows",
  5417. page: "page",
  5418. total: "total",
  5419. records: "records",
  5420. repeatitems: true,
  5421. cell: "cell",
  5422. id: "id",
  5423. userdata: "userdata",
  5424. subgrid: { root: "rows", repeatitems: true, cell: "cell" }
  5425. }, p.jsonReader);
  5426. p.localReader = extend(true, {
  5427. root: "rows",
  5428. page: "page",
  5429. total: "total",
  5430. records: "records",
  5431. repeatitems: false,
  5432. cell: "cell",
  5433. id: "id",
  5434. userdata: "userdata",
  5435. subgrid: { root: "rows", repeatitems: true, cell: "cell" }
  5436. }, p.localReader);
  5437. if (p.scroll) {
  5438. p.pgbuttons = false;
  5439. p.pginput = false;
  5440. p.rowList = [];
  5441. }
  5442. if (p.treeGrid === true) {
  5443. try { $j.setTreeGrid.call($self0); } catch (ignore1) { }
  5444. if (p.datatype !== "local") { p.localReader = { id: "_id_" }; }
  5445. // rebuild p.iPropByName after modification of p.additionalProperties
  5446. p.iPropByName = buildAddPropMap(p.additionalProperties);
  5447. }
  5448. normalizeRemapColumns();
  5449. buildArrayReader();
  5450. if (p.data.length) {
  5451. normalizeData.call(ts);
  5452. refreshIndex.call(ts);
  5453. }
  5454. if (p.shrinkToFit === true && p.forceFit === true) {
  5455. for (iCol = p.colModel.length - 1; iCol >= 0; iCol--) {
  5456. if (p.colModel[iCol].hidden !== true) {
  5457. p.colModel[iCol].resizable = false;
  5458. break;
  5459. }
  5460. }
  5461. }
  5462. var idn, w, res, sort, tooltip, labelStyle, ptr, sortarr = [], sortord = [], sotmp = [],
  5463. thead = "<thead><tr class='ui-jqgrid-labels' role='row'>", headerText,
  5464. tbody = "<tbody><tr style='display:none;'>",
  5465. hoverStateClasses = getGuiStyles("states.hover"),
  5466. hoverThStateClasses = getGuiStyles("states.hoverTh") || hoverStateClasses,
  5467. disabledStateClasses = getGuiStyles("states.disabled");
  5468. if (p.multiSort) {
  5469. sortarr = p.sortname.split(",");
  5470. var iSort;
  5471. for (iSort = 0; iSort < sortarr.length; iSort++) {
  5472. sotmp = trim(sortarr[iSort]).split(" ");
  5473. sortarr[iSort] = trim(sotmp[0]);
  5474. sortord[iSort] = sotmp[1] ? trim(sotmp[1]) : p.sortorder || "asc";
  5475. }
  5476. }
  5477. for (iCol = 0; iCol < p.colNames.length; iCol++) {
  5478. cmi = p.colModel[iCol];
  5479. tooltip = p.headertitles || cmi.headerTitle ? (" title='" + stripHtml(typeof cmi.headerTitle === "string" ? cmi.headerTitle : p.colNames[iCol]) + "'") : "";
  5480. thead += "<th id='" + p.id + "_" + cmi.name + "' class='" + getGuiStyles("colHeaders", "ui-th-column ui-th-" + dir + " " + (cmi.labelClasses || "")) + "'" + tooltip + ">";
  5481. idn = cmi.index || cmi.name;
  5482. switch (cmi.labelAlign) {
  5483. case "left":
  5484. labelStyle = "text-align:left;";
  5485. break;
  5486. case "right":
  5487. labelStyle = "text-align:right;";
  5488. break;
  5489. case "likeData":
  5490. labelStyle = cmi.align === undefined || cmi.align === "left" ?
  5491. "text-align:left;" : (cmi.align === "right" ? "text-align:right;" : "");
  5492. break;
  5493. default:
  5494. labelStyle = "";
  5495. }
  5496. thead += "<div id='jqgh_" + p.id + "_" + cmi.name + "'" +
  5497. (isMSIE ? " class='ui-th-div-ie'" : "") +
  5498. (labelStyle === "" ? "" : " style='" + labelStyle + "'") + " role='columnheader'>";
  5499. headerText = (cmi.autoResizable && cmi.formatter !== "actions") || cmi.rotated ?
  5500. "<span class='" + p.autoResizing.wrapperClassName + "'>" + p.colNames[iCol] + "</span>" :
  5501. p.colNames[iCol];
  5502. if (p.sortIconsBeforeText) {
  5503. thead += (p.builderSortIcons || jgrid.builderSortIcons).call(ts, iCol);
  5504. thead += headerText;
  5505. } else {
  5506. thead += headerText;
  5507. thead += (p.builderSortIcons || jgrid.builderSortIcons).call(ts, iCol);
  5508. }
  5509. thead += "</div></th>";
  5510. tbody += "<td></td>";
  5511. cmi.width = cmi.width ? parseInt(cmi.width, 10) : 150;
  5512. if (typeof cmi.title !== "boolean") { cmi.title = true; }
  5513. cmi.lso = "";
  5514. if (idn === p.sortname) {
  5515. p.lastsort = iCol;
  5516. cmi.lso = p.sortorder || cmi.firstsortorder || "asc";
  5517. }
  5518. if (p.multiSort) {
  5519. sotmp = inArray(idn, sortarr);
  5520. if (sotmp !== -1) {
  5521. cmi.lso = sortord[sotmp];
  5522. }
  5523. }
  5524. }
  5525. thead += "</tr></thead>";
  5526. tbody += "</tr></tbody>";
  5527. var hTable = $("<table class='" + getGuiStyles("hTable", "ui-jqgrid-htable") +
  5528. "' style='width:1px' role='presentation' aria-labelledby='gbox_" + p.id + "'>" +
  5529. thead + tbody + "</table>");
  5530. $(hTable[0].tHead)
  5531. .children("tr")
  5532. .children("th")
  5533. .hover(
  5534. function () { $(this).addClass(hoverThStateClasses); },
  5535. function () { $(this).removeClass(hoverThStateClasses); }
  5536. );
  5537. if (p.multiselect) {
  5538. $(p.cb, hTable).on("click", function () {
  5539. var highlightClass = getGuiStyles("states.select"), toCheck, emp = [],
  5540. iColCb = p.iColByName.cb,
  5541. selectUnselectRow = function (tr, toSelect) {
  5542. $(tr)[toSelect ? "addClass" : "removeClass"](highlightClass)
  5543. .attr(toSelect ?
  5544. { "aria-selected": "true", tabindex: "0" } :
  5545. { "aria-selected": "false", tabindex: "-1" });
  5546. if (iColCb !== undefined) { // p.multiselectCheckboxes
  5547. $(tr.cells[iColCb]).children("input.cbox").prop("checked", toSelect);
  5548. }
  5549. },
  5550. frozenRows = grid.fbRows,
  5551. skipClasses = disabledStateClasses + " ui-subgrid jqgroup jqfoot jqgfirstrow jqgskipselect",
  5552. id, ids = p._index, iSel;
  5553. clearArray(p.selarrrow); // p.selarrrow = [];
  5554. if (this.checked) {
  5555. toCheck = true;
  5556. p.selrow = ts.rows.length > 1 ? ts.rows[ts.rows.length - 1].id : null;
  5557. if (p.multiPageSelection && (p.datatype === "local" || p.treeGrid)) {
  5558. if (p.selectAllMode === "filtered" && p.lastSelectedData != null && p.lastSelectedData.length > 0) {
  5559. p.selarrrow = [];
  5560. for (iSel = 0; iSel < p.lastSelectedData.length; iSel++) {
  5561. if (p.lastSelectedData[iSel].hasOwnProperty(p.localReader.id)) {
  5562. p.selarrrow.push(p.idPrefix + p.lastSelectedData[iSel][p.localReader.id]);
  5563. }
  5564. }
  5565. } else if (p.data != null && p.data.length > 0 && ids != null) {
  5566. // add to selarrrow all
  5567. for (id in ids) {
  5568. if (ids.hasOwnProperty(id)) {
  5569. p.selarrrow.push(p.idPrefix + id);
  5570. }
  5571. }
  5572. }
  5573. }
  5574. } else {
  5575. toCheck = false;
  5576. p.selrow = null;
  5577. }
  5578. var selArr = toCheck ? p.selarrrow : emp;
  5579. $(ts.rows).each(function (i) {
  5580. if (!hasOneFromClasses(this, skipClasses)) {
  5581. selectUnselectRow(this, toCheck);
  5582. if ($.inArray(this.id, selArr) < 0) {
  5583. selArr.push(this.id);
  5584. }
  5585. if (frozenRows) {
  5586. selectUnselectRow(frozenRows[i], toCheck);
  5587. }
  5588. }
  5589. });
  5590. feedback.call(ts, "onSelectAll", toCheck ? p.selarrrow : emp, toCheck);
  5591. // it's important don't use return false in the event handler
  5592. // the usage of return false break checking/unchecking
  5593. });
  5594. }
  5595. if (p.autowidth === true) {
  5596. var pw = Math.floor($(eg).innerWidth());
  5597. p.width = pw > 0 ? pw : "nw";
  5598. }
  5599. if (!isNaN(p.width)) { // process values like "500" instead of the number 500.
  5600. p.width = Number(p.width);
  5601. } else if (!isNaN(parseFloat(p.width))) { // process values like "500px"
  5602. p.width = parseFloat(p.width);
  5603. }
  5604. p.widthOrg = p.width;
  5605. setInitialColWidth();
  5606. $(eg).css("width", grid.width + "px")
  5607. .append("<div class='" + getGuiStyles("resizer", "ui-jqgrid-resize-mark") + "' id='" + p.rsId + "'>&#160;</div>");
  5608. $(p.rs)
  5609. .on("selectstart", function () {
  5610. return false;
  5611. })
  5612. .click(myResizerClickHandler)
  5613. .dblclick(function (e) {
  5614. var iColIndex = $(this).data("idx"),
  5615. pageX = $(this).data("pageX"),
  5616. cm = p.colModel[iColIndex];
  5617. if (pageX == null || cm == null) {
  5618. return false;
  5619. }
  5620. var arPageX = String(pageX).split(";"),
  5621. pageX1 = parseFloat(arPageX[0]),
  5622. pageX2 = parseFloat(arPageX[1]);
  5623. if (arPageX.length === 2 && (Math.abs(pageX1 - pageX2) > 5 || Math.abs(e.pageX - pageX1) > 5 || Math.abs(e.pageX - pageX2) > 5)) {
  5624. return false;
  5625. }
  5626. if (feedback.call(ts, "resizeDblClick", iColIndex, cm, e) && cm.autoResizable) {
  5627. $j.autoResizeColumn.call($self0, iColIndex);
  5628. }
  5629. feedback.call(ts, "afterResizeDblClick", { iCol: iColIndex, cm: cm, cmName: cm.name });
  5630. return false; // stop propagate
  5631. });
  5632. $(gv).css("width", grid.width + "px");
  5633. var tfoot = "";
  5634. if (p.footerrow) {
  5635. tfoot += "<table role='presentation' style='width:1px' class='" +
  5636. getGuiStyles("gridFooter", "ui-jqgrid-ftable") +
  5637. "'><tbody><tr role='row' class='" + getGuiStyles("rowFooter", "footrow footrow-" + dir) + "'>";
  5638. }
  5639. var firstr = "<tr class='" + getGuiStyles("gridRow", "jqgfirstrow ui-row-" + p.direction) + "' role='row' style='height:auto'>";
  5640. p.disableClick = false;
  5641. $("th", hTable[0].tHead.rows[0])
  5642. .each(function (j) {
  5643. var cm = p.colModel[j], nm = cm.name, $th = $(this),
  5644. $sortableDiv = $th.children("div"),
  5645. $iconsSpan = $sortableDiv.children("span.s-ico"),
  5646. showOneSortIcon = p.showOneSortIcon;
  5647. w = cm.width;
  5648. if (cm.resizable === undefined) { cm.resizable = true; }
  5649. if (cm.resizable) {
  5650. res = document.createElement("span");
  5651. $(res).html("&#160;")
  5652. .addClass("ui-jqgrid-resize ui-jqgrid-resize-" + dir)
  5653. //.css("cursor","col-resize")
  5654. .on("selectstart", function () {
  5655. return false;
  5656. });
  5657. $th.addClass(p.resizeclass);
  5658. } else {
  5659. res = "";
  5660. }
  5661. $th.css("width", w + "px")
  5662. .prepend(res);
  5663. res = null;
  5664. var hdcol = "";
  5665. if (cm.hidden === true) {
  5666. $th.css("display", "none");
  5667. hdcol = "display:none;";
  5668. }
  5669. firstr += "<td role='gridcell' " + (cm.classes ? "class='" + cm.classes + "' " : "") +
  5670. "style='height:0;width:" + w + "px;" + hdcol + "'></td>";
  5671. grid.headers[j] = { width: w, el: this };
  5672. sort = cm.sortable;
  5673. if (typeof sort !== "boolean") { cm.sortable = true; sort = true; }
  5674. if (!(nm === "cb" || nm === "subgrid" || nm === "rn") && sort) {
  5675. if (p.viewsortcols[2]) {
  5676. // class ui-jqgrid-sortable changes the cursor in
  5677. $sortableDiv.addClass("ui-jqgrid-sortable");
  5678. }
  5679. }
  5680. if (sort) {
  5681. if (p.multiSort) {
  5682. var notLso = cm.lso === "desc" ? "asc" : "desc";
  5683. if (p.viewsortcols[0]) {
  5684. $iconsSpan.css("display", "");
  5685. if (cm.lso) {
  5686. $iconsSpan.children("span.ui-icon-" + cm.lso).removeClass(disabledStateClasses);
  5687. if (showOneSortIcon) {
  5688. $iconsSpan.children("span.ui-icon-" + notLso).hide();
  5689. }
  5690. }
  5691. } else if (cm.lso) {
  5692. $iconsSpan.css("display", "");
  5693. $iconsSpan.children("span.ui-icon-" + cm.lso).removeClass(disabledStateClasses);
  5694. if (showOneSortIcon) {
  5695. $iconsSpan.children("span.ui-icon-" + notLso).hide();
  5696. }
  5697. }
  5698. if (p.showSortOrder) {
  5699. sotmp = inArray(nm, sortarr);
  5700. $iconsSpan[p.sortOrderPosition === "beforeSortIcons" ? "before" : "after"]("<span class='ui-jqgrid-sort-order'>" +
  5701. (sotmp < 0 ?
  5702. "&nbsp;" :
  5703. isFunction(p.formatSortOrder) ?
  5704. p.formatSortOrder.call(ts, { cm: this, sortIndex: sotmp }) :
  5705. sotmp + 1) +
  5706. "</span>");
  5707. }
  5708. } else {
  5709. var notSortOrder = p.sortorder === "desc" ? "asc" : "desc";
  5710. if (p.viewsortcols[0]) {
  5711. $iconsSpan.css("display", "");
  5712. if (j === p.lastsort) {
  5713. $iconsSpan.children("span.ui-icon-" + p.sortorder).removeClass(disabledStateClasses);
  5714. if (showOneSortIcon) {
  5715. $iconsSpan.children("span.ui-icon-" + notSortOrder).hide();
  5716. }
  5717. }
  5718. } else if (j === p.lastsort && cm.lso !== "") { // p.sortname === (cm.index || nm)
  5719. $iconsSpan.css("display", "");
  5720. $iconsSpan.children("span.ui-icon-" + p.sortorder).removeClass(disabledStateClasses);
  5721. if (showOneSortIcon) {
  5722. $iconsSpan.children("span.ui-icon-" + notSortOrder).hide();
  5723. }
  5724. }
  5725. }
  5726. }
  5727. if (p.footerrow) { tfoot += "<td role='gridcell' " + formatCol(j, 0, "", null, "", false) + ">&#160;</td>"; }
  5728. })
  5729. .mousedown(function (e) {
  5730. var $th = $(this), isFrozen = $th.closest(".ui-jqgrid-hdiv").hasClass("frozen-div"),
  5731. getOffset = function () {
  5732. var ret = [$th.position().left + $th.outerWidth()];
  5733. if (p.direction === "rtl") { ret[0] = p.width - ret[0]; }
  5734. ret[0] -= isFrozen ? 0 : grid.bDiv.scrollLeft;
  5735. ret.push($(grid.hDiv).position().top);
  5736. ret.push($(grid.bDiv).offset().top - $(grid.hDiv).offset().top + $(grid.bDiv).height() +
  5737. (grid.sDiv ? $(grid.sDiv).height() : 0));
  5738. return ret;
  5739. },
  5740. iCol1;
  5741. if ($(e.target).closest("th>span.ui-jqgrid-resize").length !== 1) { return; }
  5742. iCol1 = getColumnHeaderIndex(this);
  5743. if (iCol1 != null) {
  5744. if (p.forceFit === true) { p.nv = nextVisible(iCol1); }
  5745. grid.dragStart(iCol1, e, getOffset(), $th);
  5746. }
  5747. return false;
  5748. })
  5749. .click(function (e) {
  5750. if (p.disableClick) {
  5751. p.disableClick = false;
  5752. return false;
  5753. }
  5754. var s = "th.ui-th-column>div", r, d;
  5755. if (!p.viewsortcols[2]) {
  5756. s += ">span.s-ico>span.ui-grid-ico-sort"; // sort only on click on sorting icon
  5757. } else {
  5758. s += ".ui-jqgrid-sortable";
  5759. }
  5760. var t = $(e.target).closest(s);
  5761. if (t.length !== 1) { return; }
  5762. if (!p.viewsortcols[2]) {
  5763. r = true;
  5764. d = t.hasClass("ui-icon-desc") ? "asc" : "desc";
  5765. }
  5766. var iColByName = getColumnHeaderIndex(this);
  5767. if (iColByName != null) {
  5768. // the $("div", this)[0].id looks like "jqgh_" + p.id + "_" + colIndex (like "jqgh_list_invdate")
  5769. sortData.call(ts, $("div", this)[0].id.substring(5 + p.id.length + 1), iColByName, r, d, this, e);
  5770. }
  5771. return false;
  5772. });
  5773. if (p.sortable && isFunction($j.sortableColumns)) {
  5774. try {
  5775. $j.sortableColumns.call($self0, $(hTable[0].tHead.rows[0]));
  5776. } catch (ignore1) { }
  5777. }
  5778. if (p.footerrow) { tfoot += "</tr></tbody></table>"; }
  5779. firstr += "</tr>";
  5780. $self0.html("<tbody>" + firstr + "</tbody>");
  5781. //firstr = null;
  5782. $self0.addClass(getGuiStyles("grid", "ui-jqgrid-btable" + (p.altRows === true && $self0.jqGrid("isBootstrapGuiStyle") ? " table-striped" : "")));
  5783. var hg = (p.caption && p.hiddengrid === true) ? true : false,
  5784. hb = $("<div class='ui-jqgrid-hbox" + (dir === "rtl" ? "-rtl" : "") + "'></div>"),
  5785. topClasses = getGuiStyles("top"),
  5786. bottomClasses = getGuiStyles("bottom");
  5787. grid.hDiv = document.createElement("div");
  5788. $(grid.hDiv)
  5789. .css({ width: grid.width + "px" })
  5790. .addClass(getGuiStyles("hDiv", "ui-jqgrid-hdiv"))
  5791. .append(hb)
  5792. .scroll(function () {
  5793. // the hDiv can be scrolled because of tab keyboard navigation
  5794. // we have to sync bDiv and hDiv scrollLeft in the case
  5795. var bDiv = $(this).next(".ui-jqgrid-bdiv")[0];
  5796. if (bDiv) {
  5797. bDiv.scrollLeft = this.scrollLeft;
  5798. }
  5799. return false;
  5800. });
  5801. $(hb).append(hTable);
  5802. hTable = null;
  5803. if (hg) { $(grid.hDiv).hide(); }
  5804. p.rowNum = parseInt(p.rowNum, 10);
  5805. if (isNaN(p.rowNum) || p.rowNum <= 0) {
  5806. p.rowNum = p.maxRowNum;
  5807. }
  5808. if (p.pager) {
  5809. // see http://learn.jquery.com/using-jquery-core/faq/how-do-i-select-an-element-by-an-id-that-has-characters-used-in-css-notation/
  5810. // or http://api.jquery.com/id-selector/ or http://api.jquery.com/category/selectors/
  5811. // about the requirement to escape characters like ".", ":" or some other in case.
  5812. var $pager, pagerId;
  5813. if (typeof p.pager === "string" && p.pager.substr(0, 1) !== "#") {
  5814. pagerId = p.pager; // UNESCAPED id of the pager
  5815. $pager = $("#" + jqID(p.pager));
  5816. } else if (p.pager === true) {
  5817. pagerId = randId();
  5818. $pager = $("<div id='" + pagerId + "'></div>");
  5819. $pager.appendTo("body");
  5820. p.pager = "#" + jqID(pagerId);
  5821. } else {
  5822. $pager = $(p.pager); // jQuery wrapper or ESCAPED id selector
  5823. pagerId = $pager.attr("id");
  5824. }
  5825. if ($pager.length > 0) {
  5826. $pager.css({ width: grid.width + "px" }).addClass(getGuiStyles("pager.pager", "ui-jqgrid-pager " + bottomClasses)).appendTo(eg);
  5827. if (hg) { $pager.hide(); }
  5828. setPager.call(ts, pagerId, "");
  5829. p.pager = "#" + jqID(pagerId); // hold ESCAPED id selector in the pager
  5830. } else {
  5831. p.pager = ""; // clear wrong value of the pager option
  5832. }
  5833. }
  5834. if (p.cellEdit === false && p.hoverrows === true) {
  5835. $self0
  5836. .on("mouseover.jqGrid", function (e) {
  5837. ptr = $(e.target).closest("tr.jqgrow");
  5838. if ($(ptr).attr("class") !== "ui-subgrid") {
  5839. $(ptr).addClass(hoverStateClasses);
  5840. }
  5841. })
  5842. .on("mouseout.jqGrid", function (e) {
  5843. ptr = $(e.target).closest("tr.jqgrow");
  5844. $(ptr).removeClass(hoverStateClasses);
  5845. });
  5846. }
  5847. var getTdFromTarget = function (target) {
  5848. var $td, $tr, $table;
  5849. do {
  5850. $td = $(target).closest("td");
  5851. if ($td.length > 0) {
  5852. $tr = $td.parent();
  5853. $table = $tr.parent().parent();
  5854. if ($tr.is(".jqgrow") && ($table[0] === this || ($table.is("table.ui-jqgrid-btable") && ($table[0].id || "").replace("_frozen", "") === this.id))) {
  5855. break;
  5856. }
  5857. target = $td.parent();
  5858. }
  5859. } while ($td.length > 0);
  5860. return $td;
  5861. };
  5862. $self0.before(grid.hDiv)
  5863. .click(function (e) {
  5864. var highlightClass = getGuiStyles("states.select"), target = e.target,
  5865. $td = getTdFromTarget.call(ts, target), $tr = $td.parent();
  5866. // we uses ts.rows context below to be sure that we don't process the clicks in the subgrid
  5867. // probably one can change the rule and to step over the parents till one will have
  5868. // "tr.jqgrow>td" AND the parent of parent (the table element) will be ts.
  5869. // one can use the same processing in click, dblclick and contextmenu
  5870. //ptr = $(td, ts.rows).closest("tr.jqgrow");
  5871. if ($tr.length === 0 || hasOneFromClasses($tr, disabledStateClasses)) {
  5872. return;
  5873. }
  5874. var ri = $tr[0].id, ci = $td[0].cellIndex,
  5875. checkboxClicked = $(target).hasClass("cbox") &&
  5876. $(target).is(":enabled") && !hasOneFromClasses(target, disabledStateClasses),
  5877. selectionAllowed = feedback.call(ts, "beforeSelectRow", ri, e), alreadySelected = false,
  5878. editingInfo = jgrid.detectRowEditing.call(ts, ri),
  5879. locked = editingInfo != null && editingInfo.mode !== "cellEditing"; // editingInfo.savedRow.ic
  5880. if (target.tagName === "A" || (locked && !checkboxClicked)) { return; }
  5881. feedback.call(ts, "onCellSelect", ri, ci, $td.html(), e);
  5882. if (p.cellEdit === true) {
  5883. if (selectionAllowed && p.multiselect && checkboxClicked) {
  5884. setSelection.call($self0, ri, true, e);
  5885. if (checkboxClicked && !p.noCellSelection) {
  5886. return;
  5887. }
  5888. alreadySelected = true;
  5889. }
  5890. try {
  5891. $j.editCell.call($self0, $tr[0].rowIndex, ci, true);
  5892. } catch (ignore) { }
  5893. if (!p.multiselect || !p.noCellSelection || (p.multiboxonly && alreadySelected)) {
  5894. return;
  5895. }
  5896. }
  5897. if (!selectionAllowed) {
  5898. if (checkboxClicked) {
  5899. // selection is not allowed by beforeSelectRow, but the multiselect
  5900. // checkbox is clicked.
  5901. $(target).prop("checked", false);
  5902. }
  5903. return;
  5904. }
  5905. if (!p.multikey) {
  5906. if (p.multiselect && p.multiboxonly) {
  5907. if (checkboxClicked && !alreadySelected) {
  5908. setSelection.call($self0, ri, true, e);
  5909. } else {
  5910. var frz = p.frozenColumns ? p.id + "_frozen" : "";
  5911. $(p.selarrrow).each(function (i, n) {
  5912. var trid = $j.getGridRowById.call($self0, n);
  5913. if (trid) { $(trid).removeClass(highlightClass); }
  5914. $("#jqg_" + jqID(p.id) + "_" + jqID(n)).prop("checked", false);
  5915. if (frz) {
  5916. $("#" + jqID(n), "#" + jqID(frz)).removeClass(highlightClass);
  5917. $("#jqg_" + jqID(p.id) + "_" + jqID(n), "#" + jqID(frz)).prop("checked", false);
  5918. }
  5919. });
  5920. clearArray(p.selarrrow); // p.selarrrow = [];
  5921. if (!alreadySelected) {
  5922. setSelection.call($self0, ri, true, e);
  5923. }
  5924. }
  5925. } else {
  5926. var oldSelRow = p.selrow;
  5927. if (!alreadySelected) {
  5928. setSelection.call($self0, ri, true, e);
  5929. }
  5930. if (p.singleSelectClickMode === "toggle" && !p.multiselect && oldSelRow === ri) {
  5931. if (ts.grid.fbRows) {
  5932. $tr = $tr.add(
  5933. ts.grid.fbRows[$tr[0].rowIndex] === $tr[0] ?
  5934. ts.rows[$tr[0].rowIndex] :
  5935. ts.grid.fbRows[$tr[0].rowIndex]
  5936. );
  5937. }
  5938. $tr.removeClass(highlightClass).attr({ "aria-selected": "false", "tabindex": "-1" });
  5939. p.selrow = null;
  5940. }
  5941. }
  5942. } else {
  5943. if (e[p.multikey] && !alreadySelected) {
  5944. setSelection.call($self0, ri, true, e);
  5945. } else if (p.multiselect && checkboxClicked) {
  5946. checkboxClicked = $("#jqg_" + jqID(p.id) + "_" + ri).is(":checked");
  5947. $("#jqg_" + jqID(p.id) + "_" + ri).prop("checked", !checkboxClicked);
  5948. }
  5949. }
  5950. // it's important don't use return false in the event handler
  5951. // the usage of return false break checking/uchecking
  5952. })
  5953. .on("reloadGrid", function (e, opts) {
  5954. var self = this, gridSelf = self.grid, $self = $(this), p = self.p;
  5955. if (p.savedRow.length > 0 && p.reloadingDuringEditing === "prevent") {
  5956. return false;
  5957. }
  5958. if (p.treeGrid === true) {
  5959. p.datatype = p.treedatatype;
  5960. }
  5961. opts = extend({}, defaults.reloadGridOptions || {}, p.reloadGridOptions || {}, opts || {});
  5962. if (p.datatype === "local" && p.dataTypeOrg && p.loadonce && opts.fromServer) {
  5963. p.datatype = p.dataTypeOrg;
  5964. delete p.dataTypeOrg;
  5965. }
  5966. if (opts.current) {
  5967. gridSelf.selectionPreserver.call(self);
  5968. }
  5969. if (p.datatype === "local") {
  5970. if (!p.multiPageSelection) {
  5971. $j.resetSelection.call($self);
  5972. }
  5973. if (p.data.length) {
  5974. normalizeData.call(self);
  5975. refreshIndex.call(self);
  5976. }
  5977. } else if (!p.treeGrid && !p.multiPageSelection) {
  5978. p.selrow = null;
  5979. if (p.multiselect) {
  5980. clearArray(p.selarrrow); // p.selarrrow = [];
  5981. setHeadCheckBox.call(self, false);
  5982. }
  5983. clearArray(p.savedRow); // p.savedRow = [];
  5984. p.editingInfo = {};
  5985. }
  5986. cancelOrSaveEditing(p.reloadingDuringEditing);
  5987. p.iRow = -1;
  5988. p.iCol = -1;
  5989. if (p.scroll) { grid.emptyRows.call(self, true, false); }
  5990. if (opts.page) {
  5991. var page = parseInt(opts.page, 10);
  5992. if (page > p.lastpage) { page = p.lastpage; }
  5993. if (page < 1) { page = 1; }
  5994. p.page = page;
  5995. if (gridSelf.prevRowHeight) {
  5996. gridSelf.bDiv.scrollTop = (page - 1) * gridSelf.prevRowHeight * p.rowNum;
  5997. } else {
  5998. gridSelf.bDiv.scrollTop = 0;
  5999. }
  6000. }
  6001. if (gridSelf.prevRowHeight && p.scroll && opts.page === undefined) {
  6002. delete p.lastpage;
  6003. gridSelf.populateVisible.call(self);
  6004. } else {
  6005. gridSelf.populate.call(self);
  6006. }
  6007. if (p._inlinenav === true) { $self.jqGrid("showAddEditButtons", false); }
  6008. return false;
  6009. })
  6010. .dblclick(function (e) {
  6011. var $td = getTdFromTarget.call(ts, e.target), $tr = $td.parent();
  6012. // TODO: replace ts below to method which use $(this) in case of click
  6013. // on the grid and the table of the main grid if one click inside the FROZEN column
  6014. if ($td.length > 0 && !feedback.call(ts, "ondblClickRow", $tr.attr("id"), $tr[0].rowIndex, $td[0].cellIndex, e)) {
  6015. return false; // e.preventDefault() and e.stopPropagation() together
  6016. }
  6017. })
  6018. .on("contextmenu", function (e) {
  6019. var $td = getTdFromTarget.call(ts, e.target), $tr = $td.parent(), rowid = $tr.attr("id");
  6020. if ($td.length === 0) { return; }
  6021. if (!p.multiselect && p.selrow !== rowid && p.selectOnContextMenu === true) {
  6022. // TODO: replace $self0 and ts below to method which use $(this) in case of click
  6023. // on the grid and the table of the main grid if one click inside the FROZEN column
  6024. setSelection.call($self0, rowid, true, e);
  6025. }
  6026. if (!feedback.call(ts, "onRightClickRow", rowid, $tr[0].rowIndex, $td[0].cellIndex, e)) {
  6027. return false; // e.preventDefault() and e.stopPropagation() together
  6028. }
  6029. });
  6030. grid.bDiv = document.createElement("div");
  6031. if (isMSIE) { if (String(p.height).toLowerCase() === "auto") { p.height = "100%"; } }
  6032. $(grid.bDiv)
  6033. .append($("<div style='position:relative;'></div>").append("<div></div>").append(ts))
  6034. .addClass("ui-jqgrid-bdiv")
  6035. .css({ height: p.height + (isNaN(p.height) ? "" : "px"), width: (grid.width) + "px" })
  6036. .scroll(grid.scrollGrid);
  6037. if (p.maxHeight) {
  6038. $(grid.bDiv).css("max-height", p.maxHeight + (isNaN(p.maxHeight) ? "" : "px"));
  6039. }
  6040. $self0.css({ width: "1px" });
  6041. if (!$.support.tbody) { //IE
  6042. if ($(">tbody", ts).length === 2) { $(">tbody:gt(0)", ts).remove(); }
  6043. }
  6044. if (p.multikey) {
  6045. $(grid.bDiv).on(jgrid.msie ? "selectstart" : "mousedown", function () { return false; });
  6046. }
  6047. if (hg) { $(grid.bDiv).hide(); }
  6048. grid.cDiv = document.createElement("div");
  6049. var visibleGridIcon = getIcon("gridMinimize.visible"), hiddenGridIcon = getIcon("gridMinimize.hidden"), showhide = getDef("showhide"),
  6050. arf = p.hidegrid === true ?
  6051. $("<a role='link' class='" + getGuiStyles("titleButton", "ui-jqgrid-titlebar-close") + "'" + (showhide ? " title='" + showhide + "'" : "") + "/>")
  6052. .hover(
  6053. function () { arf.addClass(hoverStateClasses); },
  6054. function () { arf.removeClass(hoverStateClasses); }
  6055. )
  6056. .append("<span class='" + visibleGridIcon + "'></span>") :
  6057. "";
  6058. $(grid.cDiv).append("<span class='ui-jqgrid-title'>" + p.caption + "</span>")
  6059. .append(arf)
  6060. .addClass(getGuiStyles("gridTitle", "ui-jqgrid-titlebar ui-jqgrid-caption" + (dir === "rtl" ? "-rtl " : " ") + topClasses));
  6061. $(grid.cDiv).insertBefore(grid.hDiv);
  6062. if (p.toolbar[0]) {
  6063. grid.uDiv = document.createElement("div");
  6064. if (p.toolbar[1] === "top") {
  6065. $(grid.uDiv).insertBefore(grid.hDiv);
  6066. } else if (p.toolbar[1] === "bottom") {
  6067. $(grid.uDiv).insertAfter(grid.hDiv);
  6068. }
  6069. var toolbarUpperClasses = getGuiStyles("toolbarUpper", "ui-userdata");
  6070. if (p.toolbar[1] === "both") {
  6071. grid.ubDiv = document.createElement("div");
  6072. $(grid.uDiv).addClass(toolbarUpperClasses).attr("id", "t_" + p.id).insertBefore(grid.hDiv);
  6073. $(grid.ubDiv).addClass(getGuiStyles("toolbarBottom", "ui-userdata")).attr("id", "tb_" + p.id).insertAfter(grid.hDiv);
  6074. if (hg) { $(grid.ubDiv).hide(); }
  6075. } else {
  6076. $(grid.uDiv).width(grid.width).addClass(toolbarUpperClasses).attr("id", "t_" + p.id);
  6077. }
  6078. if (hg) { $(grid.uDiv).hide(); }
  6079. }
  6080. if (typeof p.datatype === "string") {
  6081. p.datatype = p.datatype.toLowerCase();
  6082. }
  6083. if (p.toppager) {
  6084. p.toppager = p.id + "_toppager";
  6085. grid.topDiv = $("<div id='" + p.toppager + "'></div>")[0];
  6086. $(grid.topDiv)
  6087. .addClass(getGuiStyles("pager.pager", "ui-jqgrid-toppager" + (p.caption ? "" : " " + topClasses)))
  6088. .css({ width: grid.width + "px" })
  6089. .insertBefore(grid.hDiv);
  6090. setPager.call(ts, p.toppager, "_t");
  6091. p.toppager = "#" + jqID(p.toppager); // hold ESCAPED id selector in the toppager option
  6092. } else if (p.pager === "" && !p.scroll) {
  6093. p.rowNum = p.maxRowNum;
  6094. }
  6095. if (p.footerrow) {
  6096. grid.sDiv = $("<div class='ui-jqgrid-sdiv'></div>")[0];
  6097. hb = $("<div class='ui-jqgrid-hbox" + (dir === "rtl" ? "-rtl" : "") + "'></div>");
  6098. $(grid.sDiv).append(hb).width(grid.width).insertAfter(grid.hDiv);
  6099. $(hb).append(tfoot);
  6100. grid.footers = $(".ui-jqgrid-ftable", grid.sDiv)[0].rows[0].cells;
  6101. if (p.rownumbers) { grid.footers[0].className = getGuiStyles("rowNum", "jqgrid-rownum"); }
  6102. if (hg) { $(grid.sDiv).hide(); }
  6103. }
  6104. hb = null;
  6105. if (p.caption) {
  6106. var tdt = p.datatype;
  6107. if (p.hidegrid === true) {
  6108. $(".ui-jqgrid-titlebar-close", grid.cDiv).click(function (e) {
  6109. var elems = ".ui-jqgrid-bdiv,.ui-jqgrid-hdiv,.ui-jqgrid-pager,.ui-jqgrid-sdiv", self = this;
  6110. if (p.toolbar[0] === true) {
  6111. if (p.toolbar[1] === "both") {
  6112. elems += ",#" + jqID($(grid.ubDiv).attr("id"));
  6113. }
  6114. elems += ",#" + jqID($(grid.uDiv).attr("id"));
  6115. }
  6116. var counter = $(elems, p.gView).length;
  6117. if (p.toppager) {
  6118. elems += "," + p.toppager;
  6119. }
  6120. if (p.gridstate === "visible") {
  6121. $(elems, p.gBox).slideUp("fast", function () {
  6122. counter--;
  6123. if (counter === 0) {
  6124. $("span", self).removeClass(visibleGridIcon).addClass(hiddenGridIcon);
  6125. p.gridstate = "hidden";
  6126. if ($(p.gBox).hasClass("ui-resizable")) { $(".ui-resizable-handle", p.gBox).hide(); }
  6127. $(grid.cDiv).addClass(bottomClasses);
  6128. if (!hg) { feedback.call(ts, "onHeaderClick", p.gridstate, e); }
  6129. }
  6130. });
  6131. } else if (p.gridstate === "hidden") {
  6132. $(grid.cDiv).removeClass(bottomClasses);
  6133. $(elems, p.gBox).slideDown("fast", function () {
  6134. counter--;
  6135. if (counter === 0) {
  6136. $("span", self).removeClass(hiddenGridIcon).addClass(visibleGridIcon);
  6137. if (hg) { p.datatype = tdt; populate.call(ts); hg = false; }
  6138. p.gridstate = "visible";
  6139. if ($(p.gBox).hasClass("ui-resizable")) { $(".ui-resizable-handle", p.gBox).show(); }
  6140. if (!hg) { feedback.call(ts, "onHeaderClick", p.gridstate, e); }
  6141. }
  6142. });
  6143. }
  6144. return false;
  6145. });
  6146. if (hg) { p.datatype = "local"; $(".ui-jqgrid-titlebar-close", grid.cDiv).trigger("click"); }
  6147. }
  6148. } else {
  6149. $(grid.cDiv).hide();
  6150. $(grid.cDiv).nextAll("div:visible").first().addClass("ui-corner-top"); // set on top toolbar or toppager or on hDiv
  6151. }
  6152. $(grid.hDiv).after(grid.bDiv);
  6153. grid.eDiv = $("<div class='" + getGuiStyles("gridError", "ui-jqgrid-errorbar ui-jqgrid-errorbar-" + dir) +
  6154. "' style='display:none;'>" +
  6155. //($self0.jqGrid("isBootstrapGuiStyle") ? "<button type='button' class='close' data-dismiss='alert' aria-label='Close'><span aria-hidden='true'>&times;</span></button>" : "") +
  6156. "<span class='" + getGuiStyles("gridErrorText", "ui-jqgrid-error") + "'></span></div>")[0];
  6157. $(grid.hDiv).after(grid.eDiv);
  6158. $(eg)
  6159. .click(myResizerClickHandler)
  6160. .dblclick(function (e) { // it's still needed for Firefox
  6161. var $resizer = $(p.rs),
  6162. resizerOffset = $resizer.offset(),
  6163. iColIndex = $resizer.data("idx"),
  6164. delta = $resizer.data("delta"),
  6165. cm = p.colModel[iColIndex],
  6166. pageX = $(this).data("pageX") || $resizer.data("pageX");
  6167. if (pageX == null || cm == null) {
  6168. return false;
  6169. }
  6170. var arPageX = String(pageX).split(";"),
  6171. pageX1 = parseFloat(arPageX[0]),
  6172. pageX2 = parseFloat(arPageX[1]);
  6173. if (arPageX.length === 2 && (Math.abs(pageX1 - pageX2) > 5 || Math.abs(e.pageX - pageX1) > 5 || Math.abs(e.pageX - pageX2) > 5)) {
  6174. return false;
  6175. }
  6176. if (feedback.call(ts, "resizeDblClick", iColIndex, cm) &&
  6177. (resizerOffset.left - 1 <= e.pageX + delta && e.pageX + delta <= resizerOffset.left + $resizer.outerWidth() + 1) && cm.autoResizable) {
  6178. $j.autoResizeColumn.call($self0, iColIndex);
  6179. }
  6180. feedback.call(ts, "afterResizeDblClick", { iCol: iColIndex, cm: cm, cmName: cm.name });
  6181. return false;
  6182. });
  6183. if (!p.pager) {
  6184. $(grid.cDiv).nextAll("div:visible").filter(":last").addClass(bottomClasses); // set on bottom toolbar or footer (sDiv) or on bDiv
  6185. }
  6186. $(".ui-jqgrid-labels", grid.hDiv)
  6187. .on("selectstart", function () { return false; });
  6188. ts.formatCol = formatCol;
  6189. ts.sortData = sortData;
  6190. ts.updatepager = updatepager;
  6191. ts.refreshIndex = refreshIndex;
  6192. ts.addItemDataToColumnIndex = addItemDataToColumnIndex;
  6193. ts.removeItemDataFromColumnIndex = removeItemDataFromColumnIndex;
  6194. ts.generateValueFromColumnIndex = function (cmName, separator, delimiter) {
  6195. var uniqueTexts = $(this).jqGrid("getUniqueValueFromColumnIndex", cmName), v = "", i, len;
  6196. if (uniqueTexts != null) {
  6197. // convert to format of editoptions.value or searchoptions.value
  6198. delimiter = delimiter || ";";
  6199. separator = separator || ":";
  6200. for (i = 0, len = uniqueTexts.length; i < len; i++) {
  6201. if (v !== "") {
  6202. v += delimiter || ";";
  6203. }
  6204. v += uniqueTexts[i] + (separator || ":") + uniqueTexts[i];
  6205. }
  6206. }
  6207. return v;
  6208. };
  6209. ts.setHeadCheckBox = setHeadCheckBox;
  6210. ts.fixScrollOffsetAndhBoxPadding = fixScrollOffsetAndhBoxPadding;
  6211. ts.constructTr = constructTr;
  6212. ts.formatter = formatter;
  6213. extend(grid, { populate: populate, emptyRows: emptyRows, beginReq: beginReq, endReq: endReq });
  6214. ts.addXmlData = readInput;
  6215. ts.addJSONData = readInput;
  6216. ts.rebuildRowIndexes = rebuildRowIndexes;
  6217. ts.grid.cols = ts.rows[0].cells;
  6218. feedback.call(ts, "onInitGrid");
  6219. // fix to allow to load TreeGrid using datatype:"local", data:mydata instead of treeGrid: true
  6220. if (p.treeGrid && p.datatype === "local" && p.data != null && p.data.length > 0) {
  6221. p.datatype = "jsonstring";
  6222. p.datastr = p.data;
  6223. p.data = [];
  6224. }
  6225. populate.call(ts);
  6226. p.hiddengrid = false;
  6227. });
  6228. };
  6229. var base = $.fn.jqGrid;
  6230. jgrid.extend({
  6231. getGridRes: function (defaultPropName) {
  6232. // The problem is the following: there are already exist some properties of $.jgrid which can be used
  6233. // to set some defaults of jqGrid. It's: $.jgrid.defaults, $.jgrid.search, $.jgrid.edit, $.jgrid.view, $.jgrid.del, $.jgrid.nav
  6234. // $.jgrid.formatter, $.jgrid.errors, $.jgrid.col
  6235. // Existing programs could use the objects to set either language specific settings (which are now moved under locales part)
  6236. // be language independent. Thus one should combine language specific settings with the user's settings and overwrite the settings
  6237. // with grid specific settings if the settings exist.
  6238. //
  6239. // For example:
  6240. // p.loadtext (grid option) = "..."
  6241. // $.jgrid.defaults.loadtext = "........."
  6242. // p.locales = "en-US",
  6243. // $.jgrid.locales["en-US"].defaults.loadtext = "Loading...";
  6244. //
  6245. // p.edit.addCaption = "Add Invoice"
  6246. // $.jgrid.edit.addCaption = "Add"
  6247. // p.locales = "en-US",
  6248. // $.jgrid.locales["en-US"].edit.addCaption = "Add Record";
  6249. //
  6250. // In the case the grid option p.loadtext = "..." need be used. If p.loadtext is not defined then $.jgrid.defaults.loadtext. If
  6251. // $.jgrid.defaults.loadtext is not defined explicitly by the user, then language settings will be used
  6252. var $t = this[0];
  6253. if (!$t || !$t.grid || !$t.p) { return null; }
  6254. // One need get defaultPropName from $.jgrid root first. If no value exist then one should get it from $.jgrid[reg] root
  6255. var res = jgrid.getRes(locales[$t.p.locale], defaultPropName) || jgrid.getRes(locales["en-US"], defaultPropName),
  6256. resDef = jgrid.getRes(jgrid, defaultPropName);
  6257. return typeof res === "object" && res !== null && !$.isArray(res) ?
  6258. $.extend(true, {}, res, resDef || {}) : // !!! Expensive and can be slow !!!
  6259. resDef !== undefined ? resDef : res;
  6260. },
  6261. getGuiStyles: function (path, jqClasses) {
  6262. var $t = this instanceof $ && this.length > 0 ? this[0] : this;
  6263. if (!$t || !$t.grid || !$t.p) { return ""; }
  6264. var p = $t.p, guiStyle = p.guiStyle || jgrid.defaults.guiStyle || "jQueryUI",
  6265. guiClasses = jgrid.getRes(jgrid.guiStyles[guiStyle], path), baseGuiStyle;
  6266. if (guiClasses === undefined) {
  6267. baseGuiStyle = jgrid.getRes(jgrid.guiStyles[guiStyle], "baseGuiStyle");
  6268. if (typeof baseGuiStyle === "string") {
  6269. guiClasses = jgrid.getRes(jgrid.guiStyles[baseGuiStyle], path);
  6270. }
  6271. }
  6272. return jgrid.mergeCssClasses(guiClasses || "", jqClasses || "");
  6273. },
  6274. isBootstrapGuiStyle: function () {
  6275. return $.inArray("ui-jqgrid-bootstrap", $(this).jqGrid("getGuiStyles", "gBox").split(" ")) >= 0;
  6276. },
  6277. displayErrorMessage: function (message) {
  6278. var $t = this instanceof $ && this.length > 0 ? this[0] : this;
  6279. if (!$t || !$t.grid || !$t.p || !message) { return; }
  6280. var $errorDiv = $($t.grid.eDiv),
  6281. $errorSpan = $errorDiv.children(".ui-jqgrid-error");
  6282. $errorSpan.html(message);
  6283. $errorDiv.show();
  6284. if ($t.p.errorDisplayTimeout) {
  6285. setTimeout(function () {
  6286. $errorSpan.empty();
  6287. $errorDiv.hide();
  6288. }, $t.p.errorDisplayTimeout);
  6289. }
  6290. },
  6291. getIconRes: function (path) {
  6292. var $t = this instanceof $ && this.length > 0 ? this[0] : this;
  6293. if (!$t || !$t.p) { return ""; }
  6294. var p = $t.p, iconSet = jgrid.icons[p.iconSet],
  6295. getIcon = function (basePath, path, alternativeRoot) {
  6296. var pathParts = path.split("."), root, n = pathParts.length, part, i, classes = [];
  6297. basePath = typeof basePath === "string" ? jgrid.icons[basePath] : basePath;
  6298. if (basePath == null) {
  6299. return ""; // error unknown iconSet
  6300. }
  6301. root = basePath;
  6302. if (root.common) {
  6303. classes.push(root.common);
  6304. } else if (alternativeRoot && alternativeRoot.common) {
  6305. classes.push(alternativeRoot.common);
  6306. }
  6307. for (i = 0; i < n; i++) {
  6308. part = pathParts[i];
  6309. if (!part) {
  6310. break;
  6311. }
  6312. if (i + 1 === n && root.ignoreParents) {
  6313. // the final level
  6314. // Verify that ignoreParents mode is set on the level
  6315. classes = []; // reset array of classes
  6316. }
  6317. root = root[part];
  6318. if (root === undefined) {
  6319. if (part === "common") { break; }
  6320. return ""; // error unknown icon path
  6321. }
  6322. if (typeof root === "string") {
  6323. classes.push(root);
  6324. break;
  6325. }
  6326. if (root != null && root.common) {
  6327. classes.push(root.common);
  6328. }
  6329. }
  6330. return jgrid.mergeCssClasses.apply(this, classes);
  6331. };
  6332. if (iconSet == null) {
  6333. return "";
  6334. }
  6335. var classes = getIcon(p.iconSet, path);
  6336. if (classes === "" && iconSet.baseIconSet != null) {
  6337. classes = getIcon(iconSet.baseIconSet, path, jgrid.icons[p.iconSet]);
  6338. }
  6339. return classes || "";
  6340. },
  6341. isInCommonIconClass: function (testClass) {
  6342. var $t = this instanceof $ && this.length > 0 ? this[0] : this;
  6343. if (!$t || !$t.p) { return ""; }
  6344. var p = $t.p, iconSet = jgrid.icons[p.iconSet];
  6345. if (iconSet == null) {
  6346. return false;
  6347. }
  6348. var commonClasses = iconSet.common;
  6349. if (commonClasses === undefined) {
  6350. if (iconSet.baseIconSet == null) {
  6351. return false;
  6352. }
  6353. iconSet = jgrid.icons[iconSet.baseIconSet];
  6354. if (iconSet == null) {
  6355. return false;
  6356. }
  6357. commonClasses = iconSet.common;
  6358. }
  6359. return typeof commonClasses === "string" && $.inArray(testClass, commonClasses.split(" ")) >= 0;
  6360. },
  6361. getUniqueValueFromColumnIndex: function (cmName) {
  6362. var $t = this[0];
  6363. if (!$t || !$t.grid) { return null; }
  6364. var uniqueTexts = [], v = "", id;
  6365. var uniqueValues = $t.p.indexByColumnData[cmName];
  6366. if (uniqueValues != null) {
  6367. for (v in uniqueValues) {
  6368. if (uniqueValues.hasOwnProperty(v)) {
  6369. for (id in uniqueValues[v]) {
  6370. if (uniqueValues[v].hasOwnProperty(id)) {
  6371. v = String(uniqueValues[v][id]); // get the value in the correct case
  6372. break;
  6373. }
  6374. }
  6375. uniqueTexts.push(v);
  6376. }
  6377. }
  6378. // sort the values
  6379. if ($t.p.ignoreCase) {
  6380. if (typeof String.prototype.localeCompare === "undefined") {
  6381. // IE10 and before
  6382. uniqueTexts.sort(function (a, b) {
  6383. var aLowCase = a.toLowerCase(),
  6384. bLowCase = b.toLowerCase();
  6385. return (aLowCase === bLowCase) ? 0 : ((aLowCase > bLowCase) ? 1 : -1);
  6386. });
  6387. } else {
  6388. uniqueTexts.sort(function (a, b) {
  6389. return String(a).toLowerCase().localeCompare(String(b).toLowerCase());
  6390. });
  6391. }
  6392. } else {
  6393. uniqueTexts.sort();
  6394. }
  6395. }
  6396. return uniqueTexts;
  6397. },
  6398. generateDatalistFromColumnIndex: function (cmName) {
  6399. if (!this[0] || !this[0].grid) { return null; }
  6400. var uniqueTexts = this.jqGrid("getUniqueValueFromColumnIndex", cmName), i, len,
  6401. $dataList = $("<datalist></datalist>");
  6402. if (uniqueTexts != null && uniqueTexts.length > 0) {
  6403. // convert to format of editoptions.value or searchoptions.value
  6404. for (i = 0, len = uniqueTexts.length; i < len; i++) {
  6405. $dataList.append($("<option></option>").attr("value", uniqueTexts[i]));
  6406. }
  6407. } else {
  6408. return $(); // return empty jQuery object
  6409. }
  6410. return $dataList;
  6411. },
  6412. getGridParam: function (pName) {
  6413. var $t = this[0];
  6414. if (!$t || !$t.grid) { return null; }
  6415. if (!pName) { return $t.p; }
  6416. return $t.p[pName] !== undefined ? $t.p[pName] : null;
  6417. },
  6418. setGridParam: function (newParams, overwrite) {
  6419. return this.each(function () {
  6420. var self = this;
  6421. if (overwrite == null) {
  6422. overwrite = false;
  6423. }
  6424. if (self.grid && typeof newParams === "object") {
  6425. if (overwrite === true) {
  6426. $.extend(self.p, newParams);
  6427. } else {
  6428. $.extend(true, self.p, newParams);
  6429. }
  6430. }
  6431. });
  6432. },
  6433. abortAjaxRequest: function () {
  6434. return this.each(function () {
  6435. var self = this;
  6436. if (self.p.jqXhr != null) {
  6437. self.p.jqXhr.abort();
  6438. }
  6439. self.grid.endReq.call(self);
  6440. });
  6441. },
  6442. getGridRowById: function (rowid) {
  6443. if (rowid == null) {
  6444. return null;
  6445. }
  6446. var row, rowId = rowid.toString();
  6447. this.each(function () {
  6448. var i, rows = this.rows, tr, rowIndex;
  6449. if (this.p.rowIndexes != null) {
  6450. rowIndex = this.p.rowIndexes[rowId];
  6451. tr = rows[rowIndex];
  6452. if (tr && tr.id === rowId) {
  6453. row = tr;
  6454. }
  6455. }
  6456. if (!row) {
  6457. try {
  6458. //row = this.rows.namedItem( rowid );
  6459. i = rows.length;
  6460. while (i--) {
  6461. tr = rows[i];
  6462. if (rowId === tr.id) {
  6463. row = tr;
  6464. break;
  6465. }
  6466. }
  6467. } catch (e) {
  6468. row = $(this.grid.bDiv).find("#" + jqID(rowid));
  6469. row = row.length > 0 ? row[0] : null;
  6470. }
  6471. }
  6472. });
  6473. return row;
  6474. },
  6475. getDataIDs: function () {
  6476. var ids = [];
  6477. this.each(function () {
  6478. var rows = this.rows, len = rows.length, i, tr;
  6479. if (len && len > 0) {
  6480. for (i = 0; i < len; i++) {
  6481. tr = rows[i];
  6482. if ($(tr).hasClass("jqgrow")) {
  6483. ids.push(tr.id);
  6484. }
  6485. }
  6486. }
  6487. });
  6488. return ids;
  6489. },
  6490. /*selectDeselectRow: function (tr, toSelect, notUpdateParam) {
  6491. return this.each(function () {
  6492. var $t = this, p = $t.p, rowId = tr.id, iSel, getGuiStyles = base.getGuiStyles,
  6493. highlightClass = getGuiStyles.call($($t), "states.select"), frozenRows,
  6494. selectUnselectRow = function (tr1, toSelect) {
  6495. var method = toSelect ? "addClass" : "removeClass", iColCb = p.iColByName.cb,
  6496. attributes = toSelect ?
  6497. { "aria-selected": "true", tabindex: "0" } :
  6498. { "aria-selected": "false", tabindex: "-1" },
  6499. selectUnselectRowInTable = function (tr) {
  6500. $(tr)[method](highlightClass).attr(attributes);
  6501. if (iColCb !== undefined) { // p.multiselect or p.multiselectCheckboxes
  6502. $(tr.cells[iColCb]).children("input.cbox").prop("checked", toSelect);
  6503. }
  6504. };
  6505. selectUnselectRowInTable(tr1);
  6506. if (frozenRows) {
  6507. selectUnselectRowInTable(frozenRows[tr1.rowIndex]);
  6508. }
  6509. };
  6510. if (!$t.grid || !p || rowId === "") { return; }
  6511. frozenRows = $t.grid.fbRows;
  6512. selectUnselectRow(tr, toSelect);
  6513. if (!notUpdateParam) {
  6514. iSel = $.inArray(rowId, p.selarrrow);
  6515. if (iSel < 0 && toSelect) {
  6516. // select
  6517. p.selarrrow.push(rowId);
  6518. p.selrow = rowId;
  6519. } else if (iSel >= 0 && !toSelect) {
  6520. // deselect
  6521. p.selarrrow.splice(iSel, 1); // remove from array
  6522. p.selrow = p.selarrrow.length >= 0 ? p.selarrrow[0] : null;
  6523. }
  6524. }
  6525. });
  6526. },*/
  6527. setSelection: function (selection, onsr, e) {
  6528. return this.each(function () {
  6529. var $t = this, $self = $($t), p = $t.p, stat, pt, ner, ia, tpsr, csr, $tr, editingInfo,
  6530. getGuiStyles = base.getGuiStyles, getGridRowById = base.getGridRowById,
  6531. highlightClass = getGuiStyles.call($self, "states.select"),
  6532. disabledClasses = getGuiStyles.call($self, "states.disabled"),
  6533. frozenRows = $t.grid.fbRows,
  6534. selectUnselectRow = function (tr1, toSelect) {
  6535. var method = toSelect ? "addClass" : "removeClass", iColCb = p.iColByName.cb,
  6536. attributes = toSelect ?
  6537. { "aria-selected": "true", tabindex: "0" } :
  6538. { "aria-selected": "false", tabindex: "-1" },
  6539. selectUnselectRowInTable = function (tr) {
  6540. $(tr)[method](highlightClass).attr(attributes);
  6541. if (iColCb !== undefined) { // p.multiselect or p.multiselectCheckboxes
  6542. $(tr.cells[iColCb]).children("input.cbox").prop("checked", toSelect);
  6543. }
  6544. };
  6545. selectUnselectRowInTable(tr1);
  6546. if (frozenRows) {
  6547. selectUnselectRowInTable(frozenRows[tr1.rowIndex]);
  6548. }
  6549. };
  6550. if (selection === undefined) { return; }
  6551. onsr = onsr === false ? false : true;
  6552. if (e != null) {
  6553. // try to get tr from e.target
  6554. $tr = $(e.target).closest("tr.jqgrow");
  6555. if ($tr.length > 0) {
  6556. pt = $tr[0];
  6557. if (frozenRows/* && !$.contains($t, pt)*/) {
  6558. // The event could be inside of frozen div.
  6559. // Thus tr could be the same as trFrozen (frozenRows[pt.rowIndex])
  6560. // We normalize it based on the rowIndex.
  6561. pt = $t.rows[pt.rowIndex];
  6562. }
  6563. }
  6564. }
  6565. if (pt == null) {
  6566. pt = getGridRowById.call($self, selection);
  6567. }
  6568. if (!pt || !pt.className || pt.className.indexOf(disabledClasses) > -1) { return; }
  6569. function scrGrid(tr, bDiv) {
  6570. var ch = bDiv.clientHeight,
  6571. st = bDiv.scrollTop,
  6572. rpos = $(tr).position().top,
  6573. rh = tr.clientHeight;
  6574. if (rpos + rh >= ch + st) {
  6575. bDiv.scrollTop = rpos - (ch + st) + rh + st;
  6576. } else if (rpos < ch + st) {
  6577. if (rpos < st) {
  6578. bDiv.scrollTop = rpos;
  6579. }
  6580. }
  6581. }
  6582. if (p.scrollrows === true) {
  6583. ner = getGridRowById.call($self, selection);
  6584. if (ner != null) {
  6585. ner = ner.rowIndex;
  6586. if (ner >= 0) {
  6587. scrGrid($t.rows[ner], $t.grid.bDiv);
  6588. }
  6589. }
  6590. }
  6591. if (!p.multiselect) {
  6592. if (pt.className !== "ui-subgrid") {
  6593. if (p.selrow !== pt.id) {
  6594. if (p.selrow !== null) {
  6595. csr = getGridRowById.call($self, p.selrow);
  6596. if (csr) {
  6597. selectUnselectRow(csr, false);
  6598. }
  6599. }
  6600. selectUnselectRow(pt, true);
  6601. stat = true;
  6602. } else {
  6603. stat = false;
  6604. }
  6605. p.selrow = pt.id;
  6606. if (onsr) {
  6607. feedback.call($t, "onSelectRow", pt.id, stat, e || {});
  6608. }
  6609. }
  6610. } else {
  6611. //unselect selectall checkbox when deselecting a specific row
  6612. $t.setHeadCheckBox(false);
  6613. p.selrow = pt.id;
  6614. editingInfo = jgrid.detectRowEditing.call($t, pt.id);
  6615. ia = $.inArray(p.selrow, p.selarrrow);
  6616. if (ia === -1) {
  6617. stat = true;
  6618. p.selarrrow.push(p.selrow);
  6619. } else if (editingInfo !== null && (editingInfo.mode === "inlineEditing" || !$(e.target).hasClass("cbox"))) {
  6620. // the row is editing and selected now. The checkbox is clicked
  6621. stat = true; // set to force the checkbox stay selected
  6622. } else {
  6623. // deselect only if the row is not in editing mode
  6624. stat = false;
  6625. p.selarrrow.splice(ia, 1);
  6626. tpsr = p.selarrrow[0];
  6627. p.selrow = (tpsr === undefined) ? null : tpsr;
  6628. }
  6629. if (pt.className !== "ui-subgrid") {
  6630. selectUnselectRow(pt, stat);
  6631. }
  6632. if (onsr) {
  6633. feedback.call($t, "onSelectRow", pt.id, stat, e || {});
  6634. }
  6635. }
  6636. });
  6637. },
  6638. resetSelection: function (rowid) {
  6639. return this.each(function () {
  6640. var $t = this, $self = $(this), p = $t.p, row,
  6641. getGuiStyles = base.getGuiStyles, getGridRowById = base.getGridRowById,
  6642. highlightClass = getGuiStyles.call($self, "states.select"), //"ui-state-highlight"
  6643. cellEditCellHighlightClasses = "edit-cell " + highlightClass,
  6644. cellEditRowHighlightClasses = "selected-row " + getGuiStyles.call($self, "states.hover"),
  6645. iColCb = p.iColByName.cb,
  6646. multiselectChechboxes = iColCb !== undefined,
  6647. frozenRows = $t.grid.fbRows,
  6648. deselectRow = function (tr) {
  6649. var method = "removeClass", frozenRow,
  6650. attributes = { "aria-selected": "false", tabindex: "-1" };
  6651. $(tr)[method](highlightClass).attr(attributes);
  6652. if (multiselectChechboxes) { // p.multiselect or p.multiselectCheckboxes
  6653. $(tr.cells[iColCb]).children("input.cbox").prop("checked", false);
  6654. }
  6655. if (frozenRows) {
  6656. frozenRow = frozenRows[tr.rowIndex];
  6657. $(frozenRow)[method](highlightClass).attr(attributes);
  6658. if (multiselectChechboxes) { // p.multiselect or p.multiselectCheckboxes
  6659. $(frozenRow.cells[iColCb]).children("input.cbox").prop("checked", false);
  6660. }
  6661. }
  6662. };
  6663. if (rowid !== undefined) {
  6664. row = getGridRowById.call($self, rowid);
  6665. deselectRow(row);
  6666. if (multiselectChechboxes) {
  6667. $t.setHeadCheckBox(false);
  6668. var ia = $.inArray(rowid, p.selarrrow);
  6669. if (ia !== -1) {
  6670. p.selarrrow.splice(ia, 1);
  6671. }
  6672. }
  6673. } else if (!p.multiselect) {
  6674. if (p.selrow) {
  6675. row = getGridRowById.call($self, p.selrow);
  6676. deselectRow(row);
  6677. p.selrow = null;
  6678. }
  6679. } else {
  6680. $($t.rows).each(function () {
  6681. var iSel = $.inArray(this.id, p.selarrrow);
  6682. if (iSel !== -1) {
  6683. deselectRow(this);
  6684. p.selarrrow.splice(iSel, 1);
  6685. }
  6686. });
  6687. $t.setHeadCheckBox(false);
  6688. if (!p.multiPageSelection) {
  6689. clearArray(p.selarrrow); // p.selarrrow = [];
  6690. }
  6691. p.selrow = null;
  6692. }
  6693. if (p.cellEdit === true) {
  6694. if (parseInt(p.iCol, 10) >= 0 && parseInt(p.iRow, 10) >= 0) {
  6695. row = $t.rows[p.iRow];
  6696. if (row != null) {
  6697. $(row.cells[p.iCol]).removeClass(cellEditCellHighlightClasses);
  6698. $(row).removeClass(cellEditRowHighlightClasses);
  6699. }
  6700. if (frozenRows) {
  6701. row = frozenRows[p.iRow];
  6702. if (row != null) {
  6703. $(row.cells[p.iCol]).removeClass(cellEditCellHighlightClasses);
  6704. $(row).removeClass(cellEditRowHighlightClasses);
  6705. }
  6706. }
  6707. }
  6708. }
  6709. //clearArray(p.savedRow); // p.savedRow = [];
  6710. //p.editingInfo = {};
  6711. });
  6712. },
  6713. isCellEditing: function (rowid, iCol, trDom) {
  6714. var $t = this[0], editingInfo = jgrid.detectRowEditing.call($t, rowid);
  6715. if (editingInfo != null &&
  6716. ((editingInfo.mode === "inlineEditing") ||
  6717. (editingInfo.mode === "cellEditing" && editingInfo.savedRow.ic === iCol))) {
  6718. iCol = isNaN(iCol) ? $t.p.iColByName[iCol] : parseInt(iCol, 10);
  6719. var tr = trDom != null && trDom.id === rowid ?
  6720. trDom :
  6721. base.getGridRowById.call($($t), rowid),
  6722. cm = $t.p.colModel[iCol],
  6723. isEditable = cm.editable;
  6724. if ($.isFunction(isEditable)) {
  6725. isEditable = isEditable.call($t, {
  6726. rowid: rowid,
  6727. id: stripPref($t.p.idPrefix, rowid),
  6728. iCol: iCol,
  6729. iRow: tr.rowIndex,
  6730. cmName: cm.name,
  6731. cm: cm,
  6732. mode: editingInfo.mode,
  6733. td: tr.cells[iCol],
  6734. tr: tr,
  6735. dataElement: jgrid.getDataFieldOfCell.call($t, tr, iCol)[0]
  6736. });
  6737. }
  6738. if (isEditable === true) {
  6739. return true;
  6740. }
  6741. }
  6742. return false;
  6743. },
  6744. getRowData: function (rowid, options) {
  6745. // TODO: add additional parameter, which will inform whether the output data need be in formatted or unformatted form
  6746. var res = {}, resall;
  6747. if (typeof rowid === "object") {
  6748. options = rowid;
  6749. rowid = undefined;
  6750. }
  6751. options = options || {};
  6752. this.each(function () {
  6753. var $t = this, p = $t.p, getall = false, tr, len = 1, j, rows = $t.rows, i, $td, cm, nm, td, editingInfo;
  6754. if (rowid === undefined) {
  6755. getall = true;
  6756. resall = [];
  6757. len = rows.length;
  6758. } else {
  6759. tr = base.getGridRowById.call($($t), rowid);
  6760. if (!tr) { return res; }
  6761. }
  6762. for (j = 0; j < len; j++) {
  6763. if (getall) { tr = rows[j]; }
  6764. if ($(tr).hasClass("jqgrow")) {
  6765. editingInfo = jgrid.detectRowEditing.call($t, rowid);
  6766. $td = $(tr).find("td[role=gridcell]");
  6767. for (i = 0; i < $td.length; i++) {
  6768. cm = p.colModel[i];
  6769. nm = cm.name;
  6770. if ($.inArray(nm, p.reservedColumnNames) < 0 && cm.formatter !== "actions" && (!options.skipHidden || !cm.hidden)) {
  6771. td = $td[i];
  6772. if (base.isCellEditing.call($($t), rowid, i, tr)) {
  6773. res[nm] = jgrid.getEditedValue.call($t, jgrid.getDataFieldOfCell.call($t, tr, i), cm, {}, cm.editable);
  6774. } else if (p.treeGrid === true && nm === p.ExpandColumn) {
  6775. res[nm] = htmlDecode($("span", td).first().html());
  6776. } else {
  6777. try {
  6778. res[nm] = $.unformat.call($t, td, { rowId: rowid, colModel: cm }, i);
  6779. } catch (exception) {
  6780. res[nm] = htmlDecode($(td).html());
  6781. }
  6782. }
  6783. }
  6784. }
  6785. if (options.includeId && (p.keyName === false || res[p.keyName] == null)) {
  6786. res[p.prmNames.id] = stripPref(p.idPrefix, tr.id);
  6787. }
  6788. if (getall) {
  6789. resall.push(res);
  6790. res = {};
  6791. }
  6792. }
  6793. }
  6794. });
  6795. return resall || res;
  6796. },
  6797. delRowData: function (rowid) {
  6798. var success = false;
  6799. this.each(function () {
  6800. var $t = this, p = $t.p, editingInfo = $.jgrid.detectRowEditing.call($t, rowid), rowInd, ia, nextRow;
  6801. rowInd = base.getGridRowById.call($($t), rowid);
  6802. if (!rowInd) { return false; }
  6803. if (p.subGrid) {
  6804. nextRow = $(rowInd).next();
  6805. if (nextRow.hasClass("ui-subgrid")) {
  6806. nextRow.remove();
  6807. }
  6808. }
  6809. if (editingInfo != null) {
  6810. try {
  6811. if (editingInfo.mode === "inlineEditing" && base.restoreRow != null) {
  6812. base.restoreRow.call($($t), rowid);
  6813. } else if (editingInfo.mode === "cellEditing" && base.restoreCell != null) {
  6814. base.restoreCell.call($($t), editingInfo.savedRow.id, editingInfo.savedRow.ic);
  6815. }
  6816. } catch (ignore) { }
  6817. }
  6818. if (rowInd.rowIndex === p.iRow) { // delete row with selected/edited cell
  6819. // reset cell editing parameters in case of selected cells, but not editing
  6820. p.iRow = -1;
  6821. p.iCol = -1;
  6822. }
  6823. $(rowInd).remove();
  6824. p.records--;
  6825. p.reccount--;
  6826. $t.updatepager(true, false);
  6827. success = true;
  6828. if (p.multiselect) {
  6829. ia = $.inArray(rowid, p.selarrrow);
  6830. if (ia !== -1) { p.selarrrow.splice(ia, 1); }
  6831. }
  6832. if (p.multiselect && p.selarrrow.length > 0) {
  6833. p.selrow = p.selarrrow[p.selarrrow.length - 1];
  6834. } else if (p.selrow === rowid) {
  6835. p.selrow = null;
  6836. }
  6837. if (p.datatype === "local") {
  6838. var id = stripPref(p.idPrefix, rowid),
  6839. pos = p._index[id];
  6840. if (pos !== undefined) {
  6841. $t.removeItemDataFromColumnIndex(id);
  6842. p.data.splice(pos, 1);
  6843. $t.refreshIndex(); // ??? it could be less expansive
  6844. }
  6845. }
  6846. $t.rebuildRowIndexes();
  6847. if (p.altRows === true && success && !$($t).jqGrid("isBootstrapGuiStyle")) {
  6848. var cn = p.altclass, frozenRows = $t.grid.fbRows;
  6849. $($t.rows).each(function (i) {
  6850. var $row = $(this);
  6851. if (frozenRows) {
  6852. $row = $row.add(frozenRows[this.rowIndex]);
  6853. }
  6854. $row[i % 2 === 0 ? "addClass" : "removeClass"](cn);
  6855. });
  6856. }
  6857. feedback.call($t, "afterDelRow", rowid);
  6858. });
  6859. return success;
  6860. },
  6861. setRowData: function (rowid, data, cssp) {
  6862. // TODO: add additional parameter to setRowData which inform that input data is in formatted or unformatted form
  6863. var success = true;
  6864. this.each(function () {
  6865. var t = this, p = t.p, ind, cp = typeof cssp, lcdata = {};
  6866. if (!t.grid) { return false; }
  6867. ind = base.getGridRowById.call($(t), rowid);
  6868. if (!ind) { return false; }
  6869. if (data) {
  6870. try {
  6871. var id = stripPref(p.idPrefix, rowid), key, pos = p._index[id], newData = {},
  6872. oData = pos != null ? p.data[pos] : undefined;
  6873. $(p.colModel).each(function (i) {
  6874. var cm = this, nm = cm.name, vl = getAccessor(data, nm);
  6875. if (vl !== undefined) {
  6876. if (p.datatype === "local" && oData != null) {
  6877. vl = convertOnSaveLocally.call(t, vl, cm, oData[nm], id, oData, i);
  6878. if ($.isFunction(cm.saveLocally)) {
  6879. cm.saveLocally.call(t, { newValue: vl, newItem: lcdata, oldItem: oData, id: id, cm: cm, cmName: nm, iCol: i });
  6880. } else {
  6881. lcdata[nm] = vl;
  6882. }
  6883. }
  6884. newData[nm] = vl;
  6885. }
  6886. });
  6887. $(p.colModel).each(function (i) {
  6888. var cm = this, nm = cm.name, title, vl = getAccessor(data, nm), $td = $(ind.cells[i]);
  6889. if (vl !== undefined) {
  6890. if (p.datatype === "local" && oData != null) {
  6891. vl = lcdata[nm];
  6892. }
  6893. title = cm.title ? { "title": vl } : {};
  6894. vl = t.formatter(rowid, vl, i, data, "edit", newData);
  6895. if (cm.formatter === "select") {
  6896. title = cm.title ? { "title": stripHtml(vl) } : {};
  6897. }
  6898. var $dataFiled = $td;
  6899. if (p.treeGrid === true && nm === p.ExpandColumn) {
  6900. $dataFiled = $dataFiled.children("span.cell-wrapperleaf,span.cell-wrapper").first();
  6901. }
  6902. $dataFiled.html(vl);
  6903. $td.attr(title);
  6904. if (p.frozenColumns) {
  6905. $dataFiled = $(t.grid.fbRows[ind.rowIndex].cells[i]);
  6906. if (p.treeGrid === true && nm === p.ExpandColumn) {
  6907. $dataFiled = $dataFiled.children("span.cell-wrapperleaf,span.cell-wrapper").first();
  6908. }
  6909. $dataFiled.html(vl).attr(title);
  6910. }
  6911. }
  6912. });
  6913. if (p.datatype === "local") {
  6914. if (p.treeGrid) {
  6915. for (key in p.treeReader) {
  6916. if (p.treeReader.hasOwnProperty(key)) {
  6917. delete lcdata[p.treeReader[key]];
  6918. }
  6919. }
  6920. }
  6921. if (oData !== undefined) {
  6922. // !!!!
  6923. p.data[pos] = $.extend(true, oData, lcdata);
  6924. t.removeItemDataFromColumnIndex(id);
  6925. t.addItemDataToColumnIndex(p.data[pos], id);
  6926. }
  6927. }
  6928. feedback.call(t, "afterSetRow", {
  6929. rowid: rowid,
  6930. inputData: data,
  6931. iData: pos,
  6932. iRow: ind.rowIndex,
  6933. tr: ind,
  6934. localData: lcdata,
  6935. cssProp: cssp
  6936. });
  6937. } catch (exception) {
  6938. success = false;
  6939. }
  6940. }
  6941. if (success) {
  6942. if (cp === "string") { $(ind).addClass(cssp); } else if (cssp !== null && cp === "object") { $(ind).css(cssp); }
  6943. //$(t).triggerHandler("jqGridAfterGridComplete");
  6944. }
  6945. });
  6946. return success;
  6947. },
  6948. changeRowid: function (oldRowId, newRowId) {
  6949. return this.each(function () {
  6950. var ts = this, $self = $(ts), p = ts.p, localData, i, newCboxId, tr, $tr, cm, value;
  6951. if (!ts.grid || !p || oldRowId === newRowId) { return; }
  6952. tr = $self.jqGrid("getGridRowById", oldRowId);
  6953. if (!tr || $self.jqGrid("getGridRowById", newRowId) != null) {
  6954. // consider to throw an exception or displaying an error in some way
  6955. return;
  6956. }
  6957. var oldId = jgrid.stripPref(p.idPrefix, oldRowId),
  6958. newId = jgrid.stripPref(p.idPrefix, newRowId),
  6959. idname = p.keyName === false ? p.prmNames.id : p.keyName,
  6960. fixRowid = function () {
  6961. var id = this.id, lengthDiff = id.length - oldId.length;
  6962. if (lengthDiff > 0 && id.substr(lengthDiff) === oldId) {
  6963. $(this).attr("id", id.substr(0, lengthDiff) + newId);
  6964. }
  6965. };
  6966. if (p.iColByName[idname] >= 0) {
  6967. $self.jqGrid("setCell", oldRowId, idname, newId);
  6968. }
  6969. if (p.datatype === "local" && p._index[oldId] !== undefined) {
  6970. p._index[newId] = p._index[oldId];
  6971. localData = p.data[p._index[oldId]];
  6972. delete p._index[oldId];
  6973. if (localData.hasOwnProperty(idname)) {
  6974. localData[idname] = newId;
  6975. }
  6976. }
  6977. // fix rowIndexes used inside of getGridRowById
  6978. p.rowIndexes[newRowId] = tr.rowIndex;
  6979. delete p.rowIndexes[oldRowId];
  6980. $tr = ts.grid.fbRows == null ?
  6981. $(tr) :
  6982. $(tr).add(ts.grid.fbRows[tr.rowIndex]);
  6983. $tr.attr("id", newRowId);
  6984. if (p.selrow === oldRowId) {
  6985. p.selrow = newRowId;
  6986. }
  6987. if ($.isArray(p.selarrrow)) {
  6988. i = $.inArray(oldRowId, p.selarrrow);
  6989. if (i >= 0) {
  6990. p.selarrrow[i] = newRowId;
  6991. }
  6992. }
  6993. if (p.multiselect) {
  6994. newCboxId = "jqg_" + p.id + "_" + newRowId;
  6995. $tr.find("input.cbox")
  6996. .attr("id", newCboxId)
  6997. .attr("name", newCboxId);
  6998. }
  6999. // fix ids of all column with formatters actions and probably showlink
  7000. for (i = 0; i < p.colModel.length; i++) {
  7001. cm = p.colModel[i];
  7002. if (cm.formatter === "actions") {
  7003. $tr.find(".ui-jqgrid-actions .ui-pg-div")
  7004. .each(fixRowid);
  7005. } else if (cm.formatter === "showlink" || (cm.unformat != null && cm.formatter != null)) {
  7006. // resetting the same value in the cell will reformat the cell
  7007. // with new rowid getCell uses unformat and setCell uses unformat
  7008. value = $self.jqGrid("getCell", newRowId, i);
  7009. $self.jqGrid("setCell", newRowId, i, value, false, false, true);
  7010. }
  7011. }
  7012. feedback.call(ts, "afterChangeRowid", {
  7013. rowid: newRowId,
  7014. oldRowid: oldRowId,
  7015. iRow: tr.rowIndex,
  7016. tr: tr
  7017. });
  7018. });
  7019. },
  7020. addRowData: function (rowid, rdata, pos, src) {
  7021. // TODO: add an additional parameter, which will inform whether the input data rdata is in formatted or unformatted form
  7022. if ($.inArray(pos, ["first", "last", "before", "after", "afterSelected", "beforeSelected"]) < 0) { pos = "last"; }
  7023. var success = false, nm, row, sind, i, v, aradd, cnm, cn, data, cm, id;
  7024. if (rdata) {
  7025. if ($.isArray(rdata)) {
  7026. aradd = true;
  7027. //pos = "last";
  7028. cnm = rowid;
  7029. } else {
  7030. rdata = [rdata];
  7031. aradd = false;
  7032. }
  7033. this.each(function () {
  7034. var t = this, p = t.p, datalen = rdata.length, $self = $(t), rows = t.rows, k = 0,
  7035. getGridRowById = base.getGridRowById, colModel = p.colModel, lcdata,
  7036. additionalProperties = p.additionalProperties, grouping;
  7037. if (!aradd) {
  7038. if (rowid !== undefined) {
  7039. rowid = String(rowid);
  7040. } else {
  7041. rowid = randId();
  7042. if (p.keyName !== false) {
  7043. cnm = p.keyName;
  7044. if (rdata[0][cnm] !== undefined) { rowid = rdata[0][cnm]; }
  7045. }
  7046. }
  7047. }
  7048. cn = p.altclass;
  7049. // TODO: call jgrid.parseDataToHtml once with ALL data,
  7050. // TODO: set correct the altrow classes inside of jgrid.parseDataToHtml (use params)
  7051. while (k < datalen) {
  7052. data = rdata[k];
  7053. row = [];
  7054. if (aradd) {
  7055. try {
  7056. rowid = data[cnm];
  7057. if (rowid === undefined) {
  7058. rowid = randId();
  7059. }
  7060. } catch (exception) { rowid = randId(); }
  7061. //cna = p.altRows === true ? (rows.length - 1) % 2 === 0 ? cn : "" : "";
  7062. }
  7063. id = jgrid.stripPref(p.idPrefix, rowid);
  7064. lcdata = {};
  7065. for (i = 0; i < colModel.length; i++) {
  7066. cm = colModel[i];
  7067. nm = cm.name;
  7068. if (nm !== "rn" && nm !== "cb" && nm !== "subgrid") {
  7069. v = convertOnSaveLocally.call(t, getAccessor(data, nm), cm, undefined, id, {}, i);
  7070. if ($.isFunction(cm.saveLocally)) {
  7071. cm.saveLocally.call(t, { newValue: v, newItem: lcdata, oldItem: {}, id: id, rowid: rowid, cm: cm, cmName: nm, iCol: i });
  7072. } else if (v !== undefined) {
  7073. lcdata[nm] = v;
  7074. }
  7075. }
  7076. }
  7077. for (i = 0; i < additionalProperties.length; i++) {
  7078. nm = additionalProperties[i];
  7079. if (typeof nm === "object" && nm.hasOwnProperty("name")) {
  7080. nm = nm.name;
  7081. }
  7082. v = getAccessor(data, nm);
  7083. if (v !== undefined) {
  7084. lcdata[nm] = v;
  7085. }
  7086. }
  7087. if (p.datatype === "local") {
  7088. lcdata[p.localReader.id] = id;
  7089. p._index[id] = p.data.length;
  7090. p.data.push(lcdata);
  7091. t.addItemDataToColumnIndex(lcdata, id);
  7092. }
  7093. grouping = p.grouping;
  7094. p.grouping = false; // workaround for adding row in the grid with grouping data
  7095. row = jgrid.parseDataToHtml.call(t, 1, [rowid], [lcdata]);
  7096. p.grouping = grouping;
  7097. row = row.join("");
  7098. if (rows.length === 0) {
  7099. $(t.tBodies[0]).append(row);
  7100. } else {
  7101. if (pos === "afterSelected" || pos === "beforeSelected") {
  7102. if (src === undefined && p.selrow !== null) {
  7103. src = p.selrow;
  7104. pos = (pos === "afterSelected") ? "after" : "before";
  7105. } else {
  7106. pos = (pos === "afterSelected") ? "last" : "first";
  7107. }
  7108. }
  7109. switch (pos) {
  7110. case "last":
  7111. $(rows[rows.length - 1]).after(row);
  7112. sind = rows.length - 1;
  7113. break;
  7114. case "first":
  7115. $(rows[0]).after(row);
  7116. sind = 1;
  7117. break;
  7118. case "after":
  7119. sind = getGridRowById.call($self, src);
  7120. if (sind) {
  7121. if ($(rows[sind.rowIndex + 1]).hasClass("ui-subgrid")) {
  7122. $(rows[sind.rowIndex + 1]).after(row);
  7123. sind = sind.rowIndex + 2;
  7124. } else {
  7125. $(sind).after(row);
  7126. sind = sind.rowIndex + 1;
  7127. }
  7128. }
  7129. break;
  7130. case "before":
  7131. sind = getGridRowById.call($self, src);
  7132. if (sind) {
  7133. $(sind).before(row);
  7134. sind = sind.rowIndex - 1;
  7135. }
  7136. break;
  7137. }
  7138. }
  7139. if (p.subGrid === true) {
  7140. base.addSubGrid.call($self, p.iColByName.subgrid, sind);
  7141. }
  7142. p.records++;
  7143. p.reccount++;
  7144. if (p.lastpage === 0) {
  7145. p.lastpage = 1;
  7146. }
  7147. feedback.call(t, "afterAddRow", {
  7148. rowid: rowid,
  7149. inputData: rdata,
  7150. position: pos,
  7151. srcRowid: src,
  7152. iRow: sind,
  7153. tr: rows[sind],
  7154. localData: lcdata,
  7155. iData: p.data.length - 1
  7156. });
  7157. k++;
  7158. }
  7159. if (p.altRows === true && !aradd && !$self.jqGrid("isBootstrapGuiStyle")) {
  7160. // even in case of usage correct parameter for parseDataToHtml
  7161. // one will need to reset the classes if the row will be inserted not at the end of jqGrid
  7162. if (pos === "last") {
  7163. if ((rows.length - 1) % 2 === 0) { $(rows[rows.length - 1]).addClass(cn); }
  7164. } else {
  7165. $(rows).each(function (iRow) {
  7166. if (iRow % 2 === 1) {
  7167. $(this).addClass(cn);
  7168. } else {
  7169. $(this).removeClass(cn);
  7170. }
  7171. });
  7172. }
  7173. }
  7174. t.rebuildRowIndexes(); // we can remove the call later if pos==="last"
  7175. t.updatepager(true, true);
  7176. success = true;
  7177. });
  7178. }
  7179. return success;
  7180. },
  7181. footerData: function (action, data, format) {
  7182. // TODO: add an additional parameter, which will inform whether the input data "data" is in formatted or unformatted form
  7183. var success = false, res = {};
  7184. function isEmpty(obj) {
  7185. var i;
  7186. for (i in obj) {
  7187. if (obj.hasOwnProperty(i)) { return false; }
  7188. }
  7189. return true;
  7190. }
  7191. if (action == null) { action = "get"; }
  7192. if (typeof format !== "boolean") { format = true; }
  7193. action = action.toLowerCase();
  7194. this.each(function () {
  7195. var t = this, p = t.p, vl, $td, nm, iCol;
  7196. if (!t.grid || !p.footerrow) { return false; }
  7197. if (action === "set" && isEmpty(data)) { return false; }
  7198. success = true;
  7199. var ftable = $(t.grid.sDiv)
  7200. .children(".ui-jqgrid-hbox" + (p.direction === "rtl" ? "-rtl" : ""))
  7201. .children(".ui-jqgrid-ftable")[0];
  7202. if (ftable == null || ftable.rows == null) { return false; }
  7203. var cells = ftable.rows[0].cells, colModel = p.colModel,
  7204. fcells = t.grid.fsDiv == null ? {} : t.grid.fsDiv.children(".ui-jqgrid-ftable")[0].rows[0].cells;
  7205. if (action === "get") {
  7206. for (iCol = 0; iCol < colModel.length; iCol++) {
  7207. nm = colModel[iCol].name;
  7208. if ($.inArray(nm, p.reservedColumnNames) < 0) {
  7209. if (data !== false) {
  7210. vl = $(cells[iCol]).text();
  7211. if ($.trim(vl)) {
  7212. res[nm] = vl;
  7213. }
  7214. } else {
  7215. res[nm] = $(cells[iCol]).html();
  7216. }
  7217. }
  7218. }
  7219. } else if (action === "set") {
  7220. for (nm in data) {
  7221. iCol = p.iColByName[nm];
  7222. if (data.hasOwnProperty(nm) && iCol !== undefined) {
  7223. vl = format ? t.formatter("", data[nm], iCol, data, "edit") : data[nm];
  7224. $td = $(cells[iCol]).add(fcells[iCol]);
  7225. $td.html(vl);
  7226. if (colModel[iCol].title) {
  7227. $td.attr({ "title": stripHtml(vl) });
  7228. }
  7229. }
  7230. }
  7231. }
  7232. });
  7233. return action === "get" ? res : success;
  7234. },
  7235. resetColumnResizerHeight: function () {
  7236. return this.each(function () {
  7237. if ($.jgrid.msie) {
  7238. // IE don't calculate height: 100%; in the CSS rule
  7239. // .ui-jqgrid .ui-jqgrid-labels > .ui-th-column > .ui-jqgrid-resize { ... }
  7240. // One have to set the height of the span.ui-jqgrid-resize explicitly
  7241. // to the height of the row/th
  7242. var $th, $resizer, i, headers = this.grid.headers, headerHeight;
  7243. for (i = 0; i < headers.length; i++) {
  7244. $th = $(headers[i].el);
  7245. headerHeight = $th.height();
  7246. if (headerHeight) {
  7247. $resizer = $th.children(".ui-jqgrid-resize");
  7248. if ($resizer.length > 0 && Math.abs(headerHeight - $resizer.height()) > 0.5) {
  7249. $th.children(".ui-jqgrid-resize").height(headerHeight);
  7250. }
  7251. }
  7252. }
  7253. }
  7254. });
  7255. },
  7256. rotateColumnHeaders: function (columnNameOrIndexes, headerHeight) {
  7257. return this.each(function () {
  7258. // TODO: reorder columns via drag&drop
  7259. var $self = $(this), p = this.p, i, iCol, th, $th, thHeight, columnNameOrIndex,
  7260. $thDiv, $inconsDiv, $textWrapper, $sortOrder, widthIcon, widthText,
  7261. thPaddingLeft, thPaddingRight, thPaddingTop, thPaddingBottom,
  7262. nColFrozen = p.frozenColumns && $.isFunction(base.getNumberOfFrozenColumns) ? $self.jqGrid("getNumberOfFrozenColumns") : 0,
  7263. removeInconsDiv = function () {
  7264. $inconsDiv.detach();
  7265. /*$inconsDiv.each(function () {
  7266. this.parentNode.removeChild(this);
  7267. });*/
  7268. $sortOrder.detach();
  7269. /*$sortOrder.each(function () {
  7270. this.parentNode.removeChild(this);
  7271. });*/
  7272. },
  7273. appendInconsDiv = function () {
  7274. $thDiv.each(function (index) {
  7275. if (index < $inconsDiv.length) {
  7276. $(this).append($inconsDiv[index]);
  7277. }
  7278. if (index < $sortOrder.length) {
  7279. $(this).append($sortOrder[index]);
  7280. }
  7281. });
  7282. };
  7283. if (!$.isArray(columnNameOrIndexes)) {
  7284. columnNameOrIndexes = [columnNameOrIndexes];
  7285. }
  7286. for (i = 0; i < columnNameOrIndexes.length; i++) {
  7287. columnNameOrIndex = columnNameOrIndexes[i];
  7288. iCol = isNaN(columnNameOrIndex) ?
  7289. p.iColByName[columnNameOrIndex] :
  7290. parseInt(columnNameOrIndex, 10);
  7291. if (iCol >= 0) {
  7292. th = this.grid.headers[iCol].el;
  7293. $th = iCol < nColFrozen ?
  7294. $(th).add($(this.grid.fhDiv.find("#" + jqID(th.id)))) :
  7295. $(th);
  7296. $thDiv = $th.children("div");
  7297. $inconsDiv = $thDiv.children("span.s-ico");
  7298. $sortOrder = $thDiv.children("span.ui-jqgrid-sort-order");
  7299. $textWrapper = $thDiv.children("span." + p.autoResizing.wrapperClassName);
  7300. if ($textWrapper.length < 1) {
  7301. removeInconsDiv();
  7302. $thDiv.wrapInner("<span class='" + p.autoResizing.wrapperClassName + "'></span>");
  7303. $textWrapper = $thDiv.children("span." + p.autoResizing.wrapperClassName);
  7304. appendInconsDiv();
  7305. }
  7306. widthIcon = $inconsDiv.outerWidth(true);
  7307. widthText = $textWrapper.outerWidth();
  7308. thPaddingTop = parseFloat($th.css("padding-top") || 0);
  7309. thPaddingBottom = parseFloat($th.css("padding-bottom") || 0);
  7310. thPaddingLeft = parseFloat($th.css("padding-left") || 0);
  7311. thPaddingRight = parseFloat($th.css("padding-right") || 0);
  7312. if (p.showSortOrder) {
  7313. widthIcon += widthIcon * 0.5; // one can improve the calculation later !!!
  7314. }
  7315. thHeight = headerHeight === undefined || headerHeight === 0 ?
  7316. widthText + widthIcon + thPaddingLeft + thPaddingRight :
  7317. headerHeight;
  7318. $th.height(thHeight);
  7319. $th.css({
  7320. paddingTop: thPaddingRight + "px",
  7321. paddingBottom: thPaddingLeft + "px",
  7322. paddingLeft: thPaddingTop + "px",
  7323. paddingRight: thPaddingBottom + "px"
  7324. });
  7325. //thHeight = Math.max($th.parent().height(), thHeight);
  7326. // we must set width of column header div BEFOR adding class "ui-jqgrid-rotate" to
  7327. // prevent text cutting based on the current column width
  7328. $thDiv.css("min-width", (thHeight - thPaddingLeft - thPaddingRight) + "px")
  7329. .addClass("ui-jqgrid-rotate")
  7330. .css({ bottom: 0 });
  7331. p.colModel[iCol].rotated = true;
  7332. }
  7333. }
  7334. $self.jqGrid("resetColumnResizerHeight");
  7335. if (p.frozenColumns) {
  7336. setTimeout(function () {
  7337. $self.triggerHandler("jqGridResetFrozenHeights", {
  7338. header: {
  7339. resizeDiv: true,
  7340. resizedRows: {
  7341. iRowStart: 0,
  7342. iRowEnd: -1 // -1 means "till the end"
  7343. }
  7344. },
  7345. resizeFooter: true,
  7346. body: {
  7347. resizeDiv: true,
  7348. resizedRows: {
  7349. iRowStart: -1, // -1 means don't recalculate heights or rows
  7350. iRowEnd: -1
  7351. }
  7352. }
  7353. });
  7354. }, 0);
  7355. }
  7356. });
  7357. },
  7358. showHideCol: function (colname, show, options) {
  7359. return this.each(function () {
  7360. var $t = this, $self = $($t), grid = $t.grid, fndh = false, p = $t.p, brd = jgrid.cell_width ? 0 : p.cellLayout, cw;
  7361. if (!grid) { return; }
  7362. if (typeof colname === "string") { colname = [colname]; }
  7363. show = (show !== "none" && show !== false) ? "" : "none";
  7364. options = options || {};
  7365. var sw = show === "" ? true : false, groupHeader = p.groupHeader,
  7366. gh = groupHeader && (typeof groupHeader === "object" || $.isFunction(groupHeader));
  7367. if (gh && !options.skipSetGroupHeaders) {
  7368. base.destroyGroupHeader.call($self, false);
  7369. }
  7370. $(p.colModel).each(function (iCol) {
  7371. var setDisplayCssOnRows = function (rows) {
  7372. var iRow, nRow, row, cell, $cell, $thDiv, $inconsDiv, $textWrapper, heightText, widthText, heightIcon, widthIcon,
  7373. thHeight, thPaddingTop, thPaddingBottom, thPaddingLeft, thPaddingRight;
  7374. for (iRow = 0, nRow = rows.length; iRow < nRow; iRow++) {
  7375. row = rows[iRow];
  7376. cell = row.cells[iCol];
  7377. if (!$(row).hasClass("jqgroup") || (cell != null && cell.colSpan === 1)) {
  7378. /* workaround for the bug of Microsoft Edge
  7379. /* The following bug: Microsoft Edge "optimize" the changes of styles on elements with "height:0"
  7380. * on the empty grid. In other words, if the grid is empty then the code
  7381. * $(cell).css("display", "");
  7382. * or
  7383. * cell.style.display = "";
  7384. * will NOT change the style of the cell. One can examine cell.outerHTML to see something like
  7385. * <td role="gridcell" style="height:0;width:20px;display:none;"></td>
  7386. * but still see that cell.style.display is changed. As the workaround we first temporary set
  7387. * height of the cell from 0 to 1px, then changes "display" style and finally reset height to 0
  7388. */
  7389. $cell = $(cell);
  7390. if (iRow === 0 && $(row).hasClass("jqgfirstrow")) {
  7391. $cell.css("height", "1px");
  7392. $cell.css("display", show);
  7393. $cell.css("height", "0");
  7394. } else {
  7395. $cell.css("display", show);
  7396. }
  7397. if (sw && cell != null && cell.tagName.toUpperCase() === "TH" && $cell.hasClass("ui-th-column")) {
  7398. $thDiv = $cell.children("div");
  7399. if ($thDiv.hasClass("ui-jqgrid-rotate")) {
  7400. $inconsDiv = $thDiv.children("span.s-ico");
  7401. $textWrapper = $thDiv.children("span." + p.autoResizing.wrapperClassName),
  7402. heightText = $textWrapper.outerHeight(),
  7403. widthText = $textWrapper.outerWidth(),
  7404. heightIcon = $inconsDiv.outerHeight(),
  7405. widthIcon = $inconsDiv.outerWidth(true);
  7406. if ($textWrapper.length > 0) {
  7407. thPaddingTop = parseFloat($cell.css("padding-top") || 0);
  7408. thPaddingBottom = parseFloat($cell.css("padding-bottom") || 0);
  7409. thPaddingLeft = parseFloat($cell.css("padding-left") || 0);
  7410. thPaddingRight = parseFloat($cell.css("padding-right") || 0);
  7411. if (p.showSortOrder) {
  7412. widthIcon += widthIcon * 0.5; // one can improve the calculation later !!!
  7413. }
  7414. thHeight = widthText + widthIcon + thPaddingLeft + thPaddingRight;
  7415. $cell.height(thHeight);
  7416. $cell.css({
  7417. paddingTop: thPaddingRight + "px",
  7418. paddingBottom: thPaddingLeft + "px",
  7419. paddingLeft: thPaddingTop + "px",
  7420. paddingRight: thPaddingBottom + "px"
  7421. });
  7422. //thHeight = Math.max($cell.parent().height(), thHeight);
  7423. // we must set width of column header div BEFOR adding class "ui-jqgrid-rotate" to
  7424. // prevent text cutting based on the current column width
  7425. $thDiv.css("min-width", (thHeight - thPaddingLeft - thPaddingRight) + "px")
  7426. .css({ bottom: 0 });
  7427. }
  7428. }
  7429. }
  7430. }
  7431. // to follow HTML standards exactly one should probably add hidden column in
  7432. // grouping header row if ($(row).hasClass("jqgroup")) and decrement the value of
  7433. // colspan.
  7434. }
  7435. };
  7436. if ($.inArray(this.name, colname) !== -1 && this.hidden === sw) {
  7437. if (p.frozenColumns === true && this.frozen === true && !options.notSkipFrozen) {
  7438. return true;
  7439. }
  7440. setDisplayCssOnRows($(grid.hDiv).find(".ui-jqgrid-htable>thead>tr"));
  7441. if (p.frozenColumns === true && grid.fhDiv != null) {
  7442. setDisplayCssOnRows($(grid.fhDiv).find(".ui-jqgrid-htable>thead>tr"));
  7443. }
  7444. setDisplayCssOnRows($t.rows);
  7445. if (p.frozenColumns === true && grid.fbRows != null) {
  7446. setDisplayCssOnRows($t.rows);
  7447. }
  7448. if (p.footerrow) {
  7449. setDisplayCssOnRows($(grid.sDiv).find("tr.footrow"));
  7450. if (p.frozenColumns === true && grid.fsDiv != null) {
  7451. setDisplayCssOnRows($(grid.fsDiv).find("tr.footrow"));
  7452. }
  7453. }
  7454. cw = parseInt(this.width, 10);
  7455. if (show === "none") {
  7456. p.tblwidth -= cw + brd;
  7457. } else {
  7458. p.tblwidth += cw + brd;
  7459. }
  7460. this.hidden = !sw;
  7461. fndh = true;
  7462. if (!options.skipFeedback) {
  7463. feedback.call($t, "onShowHideCol", sw, this.name, iCol, options);
  7464. } else {
  7465. options.toReport = options.toReport || {};
  7466. options.toReport[this.name] = sw;
  7467. }
  7468. }
  7469. });
  7470. if (fndh === true) {
  7471. var newGridWidth = !p.autowidth && (p.widthOrg === undefined || p.widthOrg === "auto" || p.widthOrg === "100%") ?
  7472. p.tblwidth + parseInt(p.scrollOffset, 10) :
  7473. p.width;
  7474. if (!options.skipSetGridWidth) {
  7475. base.setGridWidth.call($self, newGridWidth);
  7476. } else {
  7477. options.newGridWidth = newGridWidth;
  7478. }
  7479. }
  7480. if (gh && !options.skipSetGroupHeaders) {
  7481. if (p.pivotOptions != null && p.pivotOptions.colHeaders != null && p.pivotOptions.colHeaders.length > 1) {
  7482. var i, gHead = p.pivotOptions.colHeaders;
  7483. for (i = 0; i < gHead.length; i++) {
  7484. // Multiple calls of setGroupHeaders for one grid are wrong,
  7485. // but there are produces good results in case of usage
  7486. // useColSpanStyle: false option. The rowspan values
  7487. // needed be increased in case of usage useColSpanStyle: true
  7488. if (gHead[i] && gHead[i].groupHeaders.length) {
  7489. base.setGroupHeaders.call($self, gHead[i]);
  7490. }
  7491. }
  7492. } else {
  7493. base.setGroupHeaders.call($self, p.groupHeader);
  7494. }
  7495. }
  7496. });
  7497. },
  7498. hideCol: function (colname, options) {
  7499. return this.each(function () { base.showHideCol.call($(this), colname, "none", options); });
  7500. },
  7501. showCol: function (colname, options) {
  7502. return this.each(function () { base.showHideCol.call($(this), colname, "", options); });
  7503. },
  7504. remapColumns: function (permutation, updateCells, keepHeader) {
  7505. var ts = this[0], p = ts.p, grid = ts.grid, iCol, n, makeArray = $.makeArray,
  7506. isFrozenColumns = p.frozenColumns === true, $toResort,
  7507. nFrozenColumns = this.jqGrid("getNumberOfFrozenColumns"),
  7508. permutationNormalized;
  7509. function normalizePermutation() {
  7510. var frozen = [], nonFrozen = [], i, l = permutation.length;
  7511. for (i = 0; i < l; i++) {
  7512. if (isFrozenColumns && permutation[i] < nFrozenColumns) {
  7513. frozen.push(permutation[i]);
  7514. } else {
  7515. nonFrozen.push(permutation[i]);
  7516. }
  7517. }
  7518. return frozen.concat(nonFrozen);
  7519. }
  7520. function resortArray(a) {
  7521. var ac = a.length ? makeArray(a) : $.extend({}, a);
  7522. $.each(permutationNormalized, function (i) {
  7523. a[i] = ac[this];
  7524. });
  7525. }
  7526. function resortRows($parent, selector) {
  7527. var $rows = selector ? $parent.children(selector) : $parent.children();
  7528. $rows.each(function () {
  7529. var row = this, elems = makeArray(row.cells);
  7530. $.each(permutationNormalized, function (i) {
  7531. var e = elems[this], oldElem = row.cells[i];
  7532. if (e != null && oldElem != null && e.cellIndex !== i) {
  7533. e.parentNode.insertBefore(e, oldElem);
  7534. }
  7535. });
  7536. });
  7537. }
  7538. if (grid == null || p == null) { return; }
  7539. // One have to "normalize" permutation array in case of usage frozen columns.
  7540. // The new index of frozen columns have to be less then nFrozenColumns
  7541. // (less then the number of frozen columns). In the same way the new index
  7542. // of non-frozen columns have to stay >=nFrozenColumns (non-frozen columns
  7543. // have to stay non-frozen)
  7544. permutationNormalized = normalizePermutation();
  7545. resortArray(p.colModel);
  7546. resortArray(p.colNames);
  7547. resortArray(grid.headers);
  7548. $toResort = $(grid.hDiv)
  7549. .children("div")
  7550. .children("table.ui-jqgrid-htable")
  7551. .children("thead");
  7552. if (isFrozenColumns && grid.fhDiv != null) {
  7553. $toResort = $toResort.add(
  7554. grid.fhDiv
  7555. .children("table.ui-jqgrid-htable")
  7556. .children("thead")
  7557. );
  7558. }
  7559. resortRows($toResort, keepHeader && ":not(.ui-jqgrid-labels)");
  7560. if (updateCells) {
  7561. $toResort = $(ts.tBodies[0]);
  7562. if (isFrozenColumns && grid.fbDiv != null) {
  7563. $toResort = $toResort.add(
  7564. grid.fbDiv
  7565. .children("table.ui-jqgrid-btable")
  7566. .children("tbody")
  7567. .first()
  7568. );
  7569. }
  7570. resortRows($toResort, "tr.jqgfirstrow,tr.jqgrow,tr.jqfoot");
  7571. }
  7572. if (p.footerrow) {
  7573. $toResort = $(grid.sDiv)
  7574. .children("div")
  7575. .children("table.ui-jqgrid-ftable")
  7576. .children("tbody")
  7577. .first();
  7578. if (isFrozenColumns && grid.fsDiv != null) {
  7579. $toResort = $toResort.add(
  7580. grid.fsDiv
  7581. .children("table.ui-jqgrid-ftable")
  7582. .children("tbody")
  7583. .first()
  7584. );
  7585. }
  7586. resortRows($toResort);
  7587. }
  7588. if (p.remapColumns) {
  7589. if (!p.remapColumns.length) {
  7590. p.remapColumns = makeArray(permutationNormalized);
  7591. } else {
  7592. resortArray(p.remapColumns);
  7593. }
  7594. }
  7595. p.lastsort = $.inArray(p.lastsort, permutationNormalized);
  7596. // rebuild iColByName
  7597. p.iColByName = {};
  7598. for (iCol = 0, n = p.colModel.length; iCol < n; iCol++) {
  7599. p.iColByName[p.colModel[iCol].name] = iCol;
  7600. }
  7601. feedback.call(ts, "onRemapColumns", permutationNormalized, updateCells, keepHeader);
  7602. },
  7603. remapColumnsByName: function (permutationByName, updateCells, keepHeader) {
  7604. var ts = this[0], p = ts.p, permutation = [], i, n, cmNames = permutationByName.slice(), inArray = $.inArray;
  7605. if (p.subGrid && inArray("subgrid", cmNames) < 0) {
  7606. cmNames.unshift("subgrid");
  7607. }
  7608. if (p.multiselect && inArray("cb", cmNames) < 0) {
  7609. cmNames.unshift("cb");
  7610. }
  7611. if (p.rownumbers && inArray("rn", cmNames) < 0) {
  7612. cmNames.unshift("rn");
  7613. }
  7614. for (i = 0, n = cmNames.length; i < n; i++) {
  7615. permutation.push(p.iColByName[cmNames[i]]);
  7616. }
  7617. base.remapColumns.call(this, permutation, updateCells, keepHeader);
  7618. return this;
  7619. },
  7620. setGridWidth: function (newWidth, shrink) {
  7621. return this.each(function () {
  7622. var $t = this, p = $t.p, columnWidth, grid = $t.grid, initialWidth = 0, iLastVariableColumn, numberOfVariableColumns = 0, hasScrollbar = false, totalVariableWidth, fixedColumnsWidth = 0, correctur,
  7623. isCellClassHidden = jgrid.isCellClassHidden, newGridWidth = newWidth;
  7624. if (!grid || p == null) { return; }
  7625. $t.fixScrollOffsetAndhBoxPadding();
  7626. // there are tree categorien of columns important below:
  7627. // 1) hidden - the columns will be not used in calculation of width
  7628. // 2) fixed - we will use the existing width of the columns in the calculation of the total width, but we well not change its width
  7629. // 3) variable columns - all other visible columns which width can be changed in general
  7630. // The width of every column consist from the innerWidth and the with of outer parts which will be 0 or cellLayout depend on boxing model used.
  7631. // The total width of the grid consist of the sum of width of all visible (fixed and variable) columns.
  7632. // There are outer bDiv which could have scroll bars. The p.scrollOffset hold the width or vertical scrollbar if it exists.
  7633. // grid.width and p.width need be set to the width of bDiv. The width of all other divs should be set to the same value.
  7634. //
  7635. // the input parameter newWidth specify new value of outer width (the width of bDiv)
  7636. var colModel = p.colModel, cm, scrollbarWidth = p.scrollOffset, borderAndPaddingWidth = jgrid.cell_width ? 0 : p.cellLayout, thInfo,
  7637. headers = grid.headers, footers = grid.footers, bDiv = grid.bDiv, hDiv = grid.hDiv, sDiv = grid.sDiv,
  7638. cols = grid.cols, delta, colsExist, shrinkFactor,
  7639. hCols = $(hDiv).find(">div>.ui-jqgrid-htable>thead>tr").first()[0].cells,
  7640. setWidthOfAllDivs = function (width) {
  7641. grid.width = p.width = width;
  7642. $(p.gBox).css("width", width + "px");
  7643. $(p.gView).css("width", width + "px");
  7644. $(bDiv).css("width", width + "px");
  7645. $(hDiv).css("width", width + "px");
  7646. if (p.pager) {
  7647. $(p.pager).css("width", width + "px");
  7648. }
  7649. if (p.toppager) {
  7650. $(p.toppager).css("width", width + "px");
  7651. }
  7652. if (p.toolbar[0] === true) {
  7653. $(grid.uDiv).css("width", width + "px");
  7654. if (p.toolbar[1] === "both") {
  7655. $(grid.ubDiv).css("width", width + "px");
  7656. }
  7657. }
  7658. if (p.footerrow) {
  7659. $(sDiv).css("width", width + "px");
  7660. }
  7661. };
  7662. if (typeof shrink !== "boolean") {
  7663. shrink = p.shrinkToFit;
  7664. }
  7665. if (isNaN(newGridWidth)) { return; }
  7666. newGridWidth = parseInt(newGridWidth, 10); // round till integer value of px
  7667. setWidthOfAllDivs(newGridWidth);
  7668. if (shrink === false && p.forceFit === true) { p.forceFit = false; }
  7669. // TODO: ??? recalculate p.tblwidth in case of shrink===false
  7670. if (shrink === true) {
  7671. // calculate initialWidth, fixedColumnsWidth and numberOfVariableColumns
  7672. $.each(colModel, function () {
  7673. // the classes property of colModel will be applied to the first
  7674. // row of the grid (hCols). If the
  7675. if (this.hidden === false && !isCellClassHidden(this.classes)) {
  7676. columnWidth = this.widthOrg;
  7677. initialWidth += columnWidth + borderAndPaddingWidth;
  7678. if (this.fixed) {
  7679. fixedColumnsWidth += this.width + borderAndPaddingWidth;
  7680. } else {
  7681. numberOfVariableColumns++;
  7682. }
  7683. }
  7684. });
  7685. if (numberOfVariableColumns === 0) { return; }
  7686. p.tblwidth = parseInt(initialWidth, 10); // round till integer value of px;
  7687. totalVariableWidth = newGridWidth - borderAndPaddingWidth * numberOfVariableColumns - fixedColumnsWidth;
  7688. if (!isNaN(p.height)) {
  7689. if (bDiv.clientHeight < bDiv.scrollHeight || $t.rows.length === 1) {
  7690. hasScrollbar = true;
  7691. totalVariableWidth -= scrollbarWidth;
  7692. }
  7693. }
  7694. shrinkFactor = totalVariableWidth / (p.tblwidth - borderAndPaddingWidth * numberOfVariableColumns - fixedColumnsWidth);
  7695. if (shrinkFactor < 0) { return; }
  7696. initialWidth = 0;
  7697. colsExist = cols.length > 0;
  7698. $.each(colModel, function (i) {
  7699. if (this.hidden === false && !isCellClassHidden(this.classes) && !this.fixed) {
  7700. columnWidth = Math.round(this.widthOrg * shrinkFactor);
  7701. this.width = columnWidth;
  7702. initialWidth += columnWidth;
  7703. headers[i].width = columnWidth;
  7704. hCols[i].style.width = columnWidth + "px";
  7705. if (p.footerrow) {
  7706. footers[i].style.width = columnWidth + "px";
  7707. }
  7708. if (colsExist) {
  7709. cols[i].style.width = columnWidth + "px";
  7710. }
  7711. iLastVariableColumn = i;
  7712. }
  7713. });
  7714. if (!iLastVariableColumn) { return; }
  7715. correctur = 0;
  7716. if (hasScrollbar) {
  7717. if (newGridWidth - fixedColumnsWidth - (initialWidth + borderAndPaddingWidth * numberOfVariableColumns) !== scrollbarWidth) {
  7718. correctur = newGridWidth - fixedColumnsWidth - (initialWidth + borderAndPaddingWidth * numberOfVariableColumns) - scrollbarWidth;
  7719. }
  7720. } else if (Math.abs(newGridWidth - fixedColumnsWidth - (initialWidth + borderAndPaddingWidth * numberOfVariableColumns)) !== 1) {
  7721. correctur = newGridWidth - fixedColumnsWidth - (initialWidth + borderAndPaddingWidth * numberOfVariableColumns);
  7722. }
  7723. cm = colModel[iLastVariableColumn];
  7724. cm.width += correctur;
  7725. p.tblwidth = parseInt(initialWidth + correctur + borderAndPaddingWidth * numberOfVariableColumns + fixedColumnsWidth, 10); // round till integer value of px;
  7726. if (p.tblwidth > newGridWidth) {
  7727. delta = p.tblwidth - parseInt(newGridWidth, 10);
  7728. p.tblwidth = newGridWidth;
  7729. cm.width = cm.width - delta;
  7730. }
  7731. columnWidth = cm.width;
  7732. thInfo = headers[iLastVariableColumn];
  7733. thInfo.width = columnWidth;
  7734. hCols[iLastVariableColumn].style.width = columnWidth + "px";
  7735. if (colsExist) { cols[iLastVariableColumn].style.width = columnWidth + "px"; }
  7736. if (p.footerrow) {
  7737. footers[iLastVariableColumn].style.width = columnWidth + "px";
  7738. }
  7739. if (p.tblwidth + (hasScrollbar ? scrollbarWidth : 0) < p.width) { // prabably bDiv.offsetWidth - bDiv.clientWidth is better as scw
  7740. // decrease the width if required
  7741. setWidthOfAllDivs(p.tblwidth + (hasScrollbar ? scrollbarWidth : 0));
  7742. }
  7743. if (bDiv.offsetWidth > bDiv.clientWidth) { // the part seems never work
  7744. // horizontal scroll bar exist.
  7745. // we need increase the width of bDiv to fix the problem or to reduce the width of the table
  7746. // currently we just increase the width
  7747. if (!p.autowidth && (p.widthOrg === undefined || p.widthOrg === "auto" || p.widthOrg === "100%")) {
  7748. setWidthOfAllDivs(bDiv.offsetWidth);
  7749. }
  7750. }
  7751. }
  7752. if (p.tblwidth) {
  7753. p.tblwidth = parseInt(p.tblwidth, 10); // round till integer value of px;
  7754. newGridWidth = p.tblwidth;
  7755. //$($t).css("width", newGridWidth + "px");
  7756. //getGridComponent(COMPONENT_NAMES.HEADER_TABLE, hDiv).css("width", newGridWidth + "px");
  7757. hDiv.scrollLeft = bDiv.scrollLeft;
  7758. /*if (p.footerrow) {
  7759. getGridComponent(COMPONENT_NAMES.FOOTER_TABLE, sDiv).css("width", newGridWidth + "px");
  7760. }*/
  7761. // small fix which origin should be examined more exactly
  7762. delta = Math.abs(newGridWidth - p.width);
  7763. if (p.shrinkToFit && !shrink && delta < 3 && delta > 0) {
  7764. if (newGridWidth < p.width) {
  7765. setWidthOfAllDivs(newGridWidth); // decrease the width if required
  7766. }
  7767. if (bDiv.offsetWidth > bDiv.clientWidth) { // the part seems never work
  7768. if (!p.autowidth && (p.widthOrg === undefined || p.widthOrg === "auto" || p.widthOrg === "100%")) {
  7769. setWidthOfAllDivs(bDiv.offsetWidth);
  7770. }
  7771. }
  7772. }
  7773. }
  7774. $t.fixScrollOffsetAndhBoxPadding();
  7775. var whichHeigthToRecalculate = {
  7776. resizeDiv: true,
  7777. resizedRows: {
  7778. iRowStart: (shrink ? 0 : -1), // -1 means don't recalculate heights or rows
  7779. iRowEnd: -1
  7780. }
  7781. };
  7782. $($t).triggerHandler("jqGridResetFrozenHeights", [{
  7783. header: whichHeigthToRecalculate,
  7784. resizeFooter: true,
  7785. body: whichHeigthToRecalculate
  7786. }]);
  7787. });
  7788. },
  7789. setGridHeight: function (nh) {
  7790. return this.each(function () {
  7791. var $t = this, grid = $t.grid, p = $t.p;
  7792. if (!grid) { return; }
  7793. var bDiv = $(grid.bDiv);
  7794. bDiv.css({ height: nh + (isNaN(nh) ? "" : "px") });
  7795. if (p.frozenColumns === true) {
  7796. //follow the original set height to use 16, better scrollbar width detection
  7797. $(p.idSel + "_frozen").parent().height(bDiv.height() - 16);
  7798. }
  7799. p.height = nh;
  7800. if (p.scroll) { grid.populateVisible.call($t); }
  7801. $t.fixScrollOffsetAndhBoxPadding();
  7802. $($t).triggerHandler("jqGridResetFrozenHeights");
  7803. });
  7804. },
  7805. setCaption: function (newcap) {
  7806. return this.each(function () {
  7807. var self = this, cDiv = self.grid.cDiv;
  7808. self.p.caption = newcap;
  7809. $("span.ui-jqgrid-title, span.ui-jqgrid-title-rtl", cDiv).html(newcap);
  7810. $(cDiv).show();
  7811. $(cDiv).nextAll("div").removeClass(base.getGuiStyles.call(self, "top"));
  7812. $(this).triggerHandler("jqGridResetFrozenHeights");
  7813. });
  7814. },
  7815. setLabel: function (colname, nData, prop, attrp) {
  7816. return this.each(function () {
  7817. var $t = this, iCol, p = $t.p, $th;
  7818. if (!$t.grid) { return; }
  7819. if (isNaN(colname)) {
  7820. iCol = p.iColByName[colname];
  7821. if (iCol === undefined) { return; }
  7822. } else { iCol = parseInt(colname, 10); }
  7823. if (iCol >= 0) {
  7824. $th = $($t.grid.headers[iCol].el);
  7825. if (p.frozenColumns) {
  7826. $th = $th.add($t.grid.fhDiv.find("#" + jqID($th)));
  7827. }
  7828. if (nData) {
  7829. $th.each(function () {
  7830. var $div = $("[id^=jqgh_]", this),
  7831. $textWrapper = $div.children("span.ui-jqgrid-cell-wrapper");
  7832. if ($textWrapper.length > 0) {
  7833. $textWrapper.html(nData);
  7834. } else {
  7835. var $ico = $(".s-ico", this);
  7836. $div.empty()
  7837. .html(nData)[p.sortIconsBeforeText ? "prepend" : "append"]($ico);
  7838. }
  7839. });
  7840. p.colNames[iCol] = nData;
  7841. }
  7842. if (prop) {
  7843. if (typeof prop === "string") { $th.addClass(prop); } else { $th.css(prop); }
  7844. }
  7845. if (typeof attrp === "object") { $th.attr(attrp); }
  7846. }
  7847. });
  7848. },
  7849. setCell: function (rowid, colName, nData, cssp, attrp, forceUpdate) {
  7850. // TODO: add an additional parameter, which will inform whether the input data nData is in formatted or unformatted form
  7851. return this.each(function () {
  7852. var $t = this, p = $t.p, iCol = -1, colModel = p.colModel, v, i, cm, item, tr, $td, $tdi, val, rawdat = {}, id, index;
  7853. if (!$t.grid) { return; }
  7854. iCol = isNaN(colName) ? p.iColByName[colName] : parseInt(colName, 10);
  7855. if (iCol >= 0) {
  7856. tr = base.getGridRowById.call($($t), rowid);
  7857. if (tr) {
  7858. $td = jgrid.getCell.call($t, tr, iCol);
  7859. if (nData !== "" || forceUpdate === true) {
  7860. cm = colModel[iCol];
  7861. if (p.datatype === "local") {
  7862. id = stripPref(p.idPrefix, rowid);
  7863. index = p._index[id];
  7864. if (index !== undefined) {
  7865. item = p.data[index];
  7866. }
  7867. }
  7868. // !!! filling of the rawdat for all cells slow down speed
  7869. // probably one should use p.data[index] (see below) instead ???
  7870. if (item == null) {
  7871. for (i = 0; i < tr.cells.length; i++) {
  7872. // !!! BUG the usage of innerHTML is wrong
  7873. // one have to use p.data[index] or unformat the data
  7874. if (i !== iCol) {
  7875. $tdi = jgrid.getDataFieldOfCell.call($t, tr, i);
  7876. if ($tdi.length > 0) {
  7877. try {
  7878. val = $.unformat.call($t, $tdi, { rowId: rowid, colModel: colModel[i] }, i);
  7879. } catch (exception) {
  7880. val = htmlDecode($tdi[0].innerHTML);
  7881. }
  7882. rawdat[colModel[i].name] = val;
  7883. }
  7884. }
  7885. }
  7886. } else {
  7887. rawdat = item;
  7888. }
  7889. rawdat[cm.name] = nData;
  7890. v = $t.formatter(rowid, nData, iCol, rawdat, "edit");
  7891. // update the data in the corresponding part of the cell
  7892. var $dataFiled = $td;
  7893. if (p.treeGrid === true && cm.name === p.ExpandColumn) {
  7894. $dataFiled = $dataFiled.children("span.cell-wrapperleaf,span.cell-wrapper").first();
  7895. }
  7896. $dataFiled.html(v);
  7897. // update the title of the cell if required
  7898. if (cm.title) {
  7899. $td.attr({ "title": nData });
  7900. }
  7901. if (item != null) { // p.datatype === "local"
  7902. v = convertOnSaveLocally.call($t, nData, cm, item[cm.name], id, item, iCol);
  7903. if ($.isFunction(cm.saveLocally)) {
  7904. cm.saveLocally.call($t, { newValue: v, newItem: item, oldItem: item, id: id, cm: cm, cmName: cm.name, iCol: iCol });
  7905. } else {
  7906. item[cm.name] = v;
  7907. // !!!!
  7908. }
  7909. }
  7910. }
  7911. if (cssp || attrp) {
  7912. $td = jgrid.getCell.call($t, tr, iCol);
  7913. if (cssp) {
  7914. $td[typeof cssp === "string" ? "addClass" : "css"](cssp);
  7915. }
  7916. if (typeof attrp === "object") {
  7917. $td.attr(attrp);
  7918. }
  7919. }
  7920. }
  7921. }
  7922. });
  7923. },
  7924. getCell: function (rowid, colName) {
  7925. // TODO: add an additional parameter, which will inform whether the output data should be in formatted or unformatted form
  7926. var ret = false;
  7927. this.each(function () {
  7928. var $t = this, iCol, p = $t.p, tr, $td, cm;
  7929. if (!$t.grid) { return; }
  7930. iCol = isNaN(colName) ? p.iColByName[colName] : parseInt(colName, 10);
  7931. if (iCol >= 0) { //isNaN(iCol)>=0 is false and undefined >= 0 is false
  7932. tr = base.getGridRowById.call($($t), rowid);
  7933. if (tr) {
  7934. $td = jgrid.getDataFieldOfCell.call($t, tr, iCol).first();
  7935. cm = p.colModel[iCol];
  7936. try {
  7937. if (base.isCellEditing.call($($t), rowid, iCol, tr)) {
  7938. ret = jgrid.getEditedValue.call($t, $td, cm, {}, cm.editable);
  7939. } else {
  7940. ret = $.unformat.call($t, $td, { rowId: tr.id, colModel: cm }, iCol);
  7941. }
  7942. } catch (exception) {
  7943. ret = htmlDecode($td.html());
  7944. }
  7945. }
  7946. }
  7947. });
  7948. return ret;
  7949. },
  7950. getCol: function (colName, obj, mathopr) {
  7951. // TODO: add an additional parameter, which will inform whether the output data should be in formatted or unformatted form
  7952. var ret = [], val, sum = 0, min, max, v;
  7953. obj = typeof obj !== "boolean" ? false : obj;
  7954. if (mathopr === undefined) { mathopr = false; }
  7955. this.each(function () {
  7956. var $t = this, iCol, p = $t.p, $td;
  7957. if (!$t.grid) { return; }
  7958. iCol = isNaN(colName) ? p.iColByName[colName] : parseInt(colName, 10);
  7959. if (iCol >= 0) { //isNaN(iCol)>=0 is false and undefined >= 0 is false
  7960. var rows = $t.rows, ln = rows.length, i = 0, dlen = 0, tr, cm = p.colModel[iCol], rowid;
  7961. if (ln && ln > 0) {
  7962. while (i < ln) {
  7963. tr = rows[i];
  7964. if ($(tr).hasClass("jqgrow")) {
  7965. $td = jgrid.getDataFieldOfCell.call($t, tr, iCol).first(); //$(tr.cells[iCol]);
  7966. rowid = tr.id;
  7967. try {
  7968. if (base.isCellEditing.call($($t), rowid, iCol, tr)) {
  7969. val = jgrid.getEditedValue.call($t, $td, cm, {}, cm.editable);
  7970. } else {
  7971. val = $.unformat.call($t, $td, { rowId: rowid, colModel: cm }, iCol);
  7972. }
  7973. } catch (exception) {
  7974. val = htmlDecode($td.html());
  7975. }
  7976. if (mathopr) {
  7977. v = parseFloat(val);
  7978. if (!isNaN(v)) {
  7979. sum += v;
  7980. if (max === undefined) { max = min = v; }
  7981. min = Math.min(min, v);
  7982. max = Math.max(max, v);
  7983. dlen++;
  7984. }
  7985. } else if (obj) {
  7986. ret.push({ id: rowid, value: val });
  7987. } else {
  7988. ret.push(val);
  7989. }
  7990. }
  7991. i++;
  7992. }
  7993. if (mathopr) {
  7994. switch (mathopr.toLowerCase()) {
  7995. case "sum":
  7996. ret = sum;
  7997. break;
  7998. case "avg":
  7999. ret = sum / dlen;
  8000. break;
  8001. case "count":
  8002. ret = (ln - 1);
  8003. break;
  8004. case "min":
  8005. ret = min;
  8006. break;
  8007. case "max":
  8008. ret = max;
  8009. break;
  8010. }
  8011. }
  8012. }
  8013. }
  8014. });
  8015. return ret;
  8016. },
  8017. clearGridData: function (clearfooter) {
  8018. return this.each(function () {
  8019. var $t = this, p = $t.p, rows = $t.rows, grid = $t.grid;
  8020. if (!grid || !p || !rows) { return; }
  8021. if (typeof clearfooter !== "boolean") { clearfooter = false; }
  8022. $($t).off(".jqGridFormatter");
  8023. grid.emptyRows.call($t, false, true);
  8024. if (p.footerrow && clearfooter) { $(".ui-jqgrid-ftable td", grid.sDiv).html("&#160;"); }
  8025. p.selrow = null;
  8026. clearArray(p.selarrrow); // p.selarrrow= [];
  8027. clearArray(p.savedRow); // p.savedRow = [];
  8028. p.editingInfo = {};
  8029. clearArray(p.data); //p.data = [];
  8030. clearArray(p.lastSelectedData); //p.lastSelectedData = [];
  8031. p._index = {};
  8032. p.rowIndexes = {};
  8033. p.dataIndexById = {};
  8034. p.indexByColumnData = {};
  8035. p.records = 0;
  8036. p.page = 1;
  8037. p.lastpage = 0;
  8038. p.reccount = 0;
  8039. $t.updatepager(true, false);
  8040. });
  8041. },
  8042. getInd: function (rowid, rc) {
  8043. var tr = base.getGridRowById.call($(this), rowid);
  8044. return tr ? (rc === true ? tr : tr.rowIndex) : false;
  8045. },
  8046. bindKeys: function (settings) {
  8047. var o = $.extend({
  8048. onEnter: null,
  8049. onSpace: null,
  8050. onLeftKey: null,
  8051. onRightKey: null,
  8052. scrollingRows: true
  8053. }, settings || {});
  8054. return this.each(function () {
  8055. var $t = this, p = $t.p, $self = $($t);
  8056. p.scrollrows = o.scrollingRows;
  8057. $self.on("keydown.jqGrid", function (event) {
  8058. var tr = $(this).find("tr[tabindex=0]")[0],
  8059. editingInfo = jgrid.detectRowEditing.call($t, $(event.target).closest("tr.jqgrow").attr("id")),
  8060. moveVertical = function (siblingProperty) {
  8061. do {
  8062. tr = tr[siblingProperty];
  8063. if (tr === null) { return; }
  8064. } while ($(tr).is(":hidden") || !$(tr).hasClass("jqgrow"));
  8065. base.setSelection.call($self, tr.id, true);
  8066. event.preventDefault();
  8067. },
  8068. feedbackKey = function (name, callbackSuffix) {
  8069. // possible events
  8070. // jqGridKeyLeft
  8071. // jqGridKeyRight
  8072. // jqGridKeyEnter
  8073. // jqGridKeySpace
  8074. // possible callbacks
  8075. // onLeftKey
  8076. // onRightKey
  8077. // onEnter
  8078. // onSpace
  8079. // no onUpKey or onDownKey and the corresponding events
  8080. var callback = o["on" + name + (callbackSuffix || "")];
  8081. $self.triggerHandler("jqGridKey" + name, [p.selrow]);
  8082. if ($.isFunction(callback)) {
  8083. callback.call($t, p.selrow);
  8084. }
  8085. },
  8086. moveHorizontal = function (stringLeftOrRight) {
  8087. if (p.treeGrid) {
  8088. var expanded = p.data[p._index[stripPref(p.idPrefix, tr.id)]][p.treeReader.expanded_field];
  8089. if (stringLeftOrRight === "Right") { expanded = !expanded; }
  8090. if (expanded) {
  8091. $(tr).find("div.treeclick").trigger("click");
  8092. }
  8093. }
  8094. feedbackKey(stringLeftOrRight, "Key");
  8095. };
  8096. //check for arrow keys
  8097. if (tr && editingInfo === null) {
  8098. switch (event.keyCode) {
  8099. case 38: // up key
  8100. moveVertical("previousSibling");
  8101. break;
  8102. case 40: // down key
  8103. moveVertical("nextSibling");
  8104. break;
  8105. case 37: // left key
  8106. moveHorizontal("Left");
  8107. break;
  8108. case 39: // left key
  8109. moveHorizontal("Right");
  8110. break;
  8111. case 13: // enter key
  8112. feedbackKey("Enter");
  8113. break;
  8114. case 32: // space key
  8115. feedbackKey("Space");
  8116. break;
  8117. default:
  8118. break;
  8119. }
  8120. }
  8121. });
  8122. });
  8123. },
  8124. unbindKeys: function () {
  8125. return this.each(function () {
  8126. $(this).off("keydown.jqGrid");
  8127. });
  8128. },
  8129. getLocalRow: function (rowid) {
  8130. var ret = false, ind;
  8131. this.each(function () {
  8132. var p = this.p;
  8133. if (rowid !== undefined && p != null && p._index != null && p.data != null) {
  8134. ind = p._index[stripPref(p.idPrefix, rowid)];
  8135. if (ind >= 0) {
  8136. ret = p.data[ind];
  8137. }
  8138. }
  8139. });
  8140. return ret;
  8141. },
  8142. progressBar: function (p) {
  8143. p = $.extend({
  8144. htmlcontent: "",
  8145. method: "hide",
  8146. loadtype: "disable"
  8147. }, p || {});
  8148. return this.each(function () {
  8149. var sh = p.method === "show" ? true : false, gridIdEscaped = jqID(this.p.id), $loading = $("#load_" + gridIdEscaped);
  8150. if (p.htmlcontent !== "") {
  8151. $loading.html(p.htmlcontent);
  8152. }
  8153. switch (p.loadtype) {
  8154. case "disable":
  8155. break;
  8156. case "enable":
  8157. $loading.toggle(sh);
  8158. break;
  8159. case "block":
  8160. $("#lui_" + gridIdEscaped).toggle(sh);
  8161. $loading.toggle(sh);
  8162. break;
  8163. }
  8164. });
  8165. },
  8166. setColWidth: function (iCol, newWidth, adjustGridWidth, skipGridAdjustments) {
  8167. return this.each(function () {
  8168. var self = this, $self = $(self), grid = self.grid, p = self.p, h;
  8169. if (typeof iCol === "string") {
  8170. // the first parametrer is column name instead of index
  8171. iCol = p.iColByName[iCol];
  8172. if (iCol === undefined) { return; }
  8173. } else if (typeof iCol !== "number") {
  8174. return; // error: wrong parameters
  8175. }
  8176. h = grid.headers[iCol];
  8177. if (h != null) {
  8178. h.newWidth = newWidth;
  8179. grid.newWidth = p.tblwidth + newWidth - h.width;
  8180. grid.resizeColumn(iCol, !p.frozenColumns, skipGridAdjustments);
  8181. if (adjustGridWidth !== false && !skipGridAdjustments) {
  8182. self.fixScrollOffsetAndhBoxPadding();
  8183. base.setGridWidth.call($self, grid.newWidth + p.scrollOffset, false); // adjust grid width too
  8184. }
  8185. }
  8186. });
  8187. },
  8188. getAutoResizableWidth: function (iCol) {
  8189. // The method get the max-width in the column.
  8190. // It get in considerations only VISIBLE elements.
  8191. // For example if some rows with data are hidden (grouping data, tree grid)
  8192. // then the max-width will see 0 as the width of the elements of the rows.
  8193. //
  8194. // The most expensive in below code is getting padding-left.
  8195. var self = this;
  8196. if (self.length === 0) {
  8197. return -1;
  8198. }
  8199. self = self[0];
  8200. var rows = self.rows, row, cell, iRow, $cell, $cellFirstChild,
  8201. p = self.p,
  8202. cm = p.colModel[iCol],
  8203. $th = $(self.grid.headers[iCol].el),
  8204. $thDiv = $th.children("div"),
  8205. thPaddingLeft = parseFloat($th.css((cm.rotated ? "padding-top" : "padding-left")) || 0), // typically 2
  8206. thPaddingRight = parseFloat($th.css((cm.rotated ? "padding-bottom" : "padding-right")) || 0),// typically 2
  8207. $incosDiv = $thDiv.children("span.s-ico"),
  8208. $sortOrder = $thDiv.children(".ui-jqgrid-sort-order"),
  8209. $wrapper = $thDiv.children("." + p.autoResizing.wrapperClassName),
  8210. wrapperOuterWidth = cm.rotated ? $wrapper.outerHeight() : $wrapper.outerWidth(),
  8211. wrapperCssWidth = parseFloat($wrapper.css(cm.rotated ? "height" : "width") || 0),
  8212. widthOuter = 0,
  8213. colWidth = 0,
  8214. compact = (cm.autoResizing != null && cm.autoResizable.compact !== undefined) ? cm.autoResizable.compact : p.autoResizing.compact,
  8215. wrapperClassName = p.autoResizing.wrapperClassName;
  8216. if (cm == null || !cm.autoResizable || $wrapper.length === 0 || cm.hidden || jgrid.isCellClassHidden(cm.classes) || cm.fixed) {
  8217. return -1; // do nothing
  8218. }
  8219. if (!compact || $incosDiv.is(":visible") || ($incosDiv.css("display") !== "none")) { //|| p.viewsortcols[0]
  8220. colWidth = cm.rotated ?
  8221. $incosDiv.outerHeight(true) :
  8222. $incosDiv.outerWidth(true) + ($sortOrder.length > 0 ? $sortOrder.outerWidth(true) : 0);
  8223. if (!p.sortIconsBeforeText) {
  8224. colWidth -= p.direction === "rtl" ?
  8225. parseFloat($incosDiv.css("padding-left") || 0) +
  8226. parseFloat($incosDiv.css("margin-left") || 0) :
  8227. parseFloat($incosDiv.css("padding-right") || 0) +
  8228. parseFloat($incosDiv.css("margin-right") || 0);
  8229. }
  8230. }
  8231. if (cm.rotated) {
  8232. colWidth = Math.max(colWidth, wrapperOuterWidth + thPaddingLeft + thPaddingRight);
  8233. } else {
  8234. colWidth += wrapperOuterWidth + thPaddingLeft +
  8235. (wrapperCssWidth === wrapperOuterWidth ? thPaddingLeft + thPaddingRight : 0) +
  8236. parseFloat($thDiv.css("margin-left") || 0) + parseFloat($thDiv.css("margin-right") || 0);
  8237. }
  8238. for (iRow = 0, rows = self.rows; iRow < rows.length; iRow++) {
  8239. row = rows[iRow];
  8240. cell = row.cells[iCol];
  8241. $cell = $(row.cells[iCol]);
  8242. if (cell != null && ($(row).hasClass("jqgrow") && row.style.display !== "none" && cell.style.display !== "none" || ($(row).hasClass("jqgroup") && cell.colSpan === 1))) {
  8243. $cellFirstChild = $(cell.firstChild);
  8244. if ($cellFirstChild.hasClass(wrapperClassName)) {
  8245. colWidth = Math.max(colWidth, $cellFirstChild.outerWidth() + widthOuter);
  8246. } else if (p.treeGrid && p.ExpandColumn === cm.name) {
  8247. $cellFirstChild = $cell.children(".cell-wrapper,.cell-wrapperleaf");
  8248. colWidth = Math.max(colWidth, $cellFirstChild.outerWidth() + widthOuter + $cell.children(".tree-wrap").outerWidth());
  8249. }
  8250. } else if ($(row).hasClass("jqgfirstrow")) {
  8251. // widthOuter is 4 typically (if jgrid.cell_width is true).
  8252. widthOuter = (jgrid.cell_width ? parseFloat($cell.css("padding-left") || 0) + parseFloat($cell.css("padding-right") || 0) : 0) +
  8253. parseFloat($cell.css("border-right") || 0) +
  8254. parseFloat($cell.css("border-left") || 0);
  8255. }
  8256. }
  8257. colWidth = Math.max(colWidth,
  8258. cm.autoResizing != null && cm.autoResizing.minColWidth !== undefined ?
  8259. cm.autoResizing.minColWidth :
  8260. p.autoResizing.minColWidth);
  8261. return Math.min(
  8262. colWidth,
  8263. cm.autoResizing != null && cm.autoResizing.maxColWidth !== undefined ?
  8264. cm.autoResizing.maxColWidth :
  8265. p.autoResizing.maxColWidth
  8266. );
  8267. },
  8268. autoResizeColumn: function (iCol, skipGridAdjustments) {
  8269. return this.each(function () {
  8270. var self = this, $self = $(this), p = self.p, cm = p.colModel[iCol], widthOrg,
  8271. $th = $(self.grid.headers[iCol].el),
  8272. newWidth = base.getAutoResizableWidth.call($self, iCol),
  8273. resetWidthOrg = (cm.autoResizing || {}).resetWidthOrg;
  8274. if (cm == null || newWidth < 0 || newWidth === cm.width) {
  8275. return;
  8276. }
  8277. base.setColWidth.call($self, iCol, newWidth, p.autoResizing.adjustGridWidth && !p.autoResizing.fixWidthOnShrink && !skipGridAdjustments, skipGridAdjustments);
  8278. if (p.autoResizing.fixWidthOnShrink && p.shrinkToFit && !skipGridAdjustments) {
  8279. cm.fixed = true;
  8280. widthOrg = cm.widthOrg; // save the value in temporary variable
  8281. cm.widthOrg = cm.width; // to force not changing of the column width
  8282. base.setGridWidth.call($self, p.width, true);
  8283. cm.widthOrg = widthOrg;
  8284. cm.fixed = false;
  8285. }
  8286. if (resetWidthOrg || (resetWidthOrg === undefined && p.autoResizing.resetWidthOrg)) {
  8287. cm.widthOrg = cm.width;
  8288. }
  8289. $th.data("autoResized", "true");
  8290. });
  8291. },
  8292. autoResizeAllColumns: function () {
  8293. return this.each(function () {
  8294. var self = this, $self = $(self), p = self.p, colModel = p.colModel, nCol = colModel.length, iCol, cm,
  8295. shrinkToFit = p.shrinkToFit, // save the original shrinkToFit value in the grid
  8296. adjustGridWidth = p.autoResizing.adjustGridWidth,
  8297. fixWidthOnShrink = p.autoResizing.fixWidthOnShrink,
  8298. width = parseInt(p.widthOrg, 10), grid = self.grid,
  8299. autoResizeColumn = base.autoResizeColumn; // cache autoResizeColumn reference
  8300. // autoResizeAllColumns calls multiple times autoResizeColumn
  8301. // which calls setColWidth, which calls resizeColumn, which calls
  8302. // fixScrollOffsetAndhBoxPadding and setGridWidth.
  8303. // The method setGridWidth will be called ADDITIONALLY by autoResizeColumn too
  8304. // As the result the most time spending by autoResizeAllColumns is
  8305. // for multiple calling of setGridWidth and fixScrollOffsetAndhBoxPadding
  8306. //
  8307. // So we skipp internal calls of fixScrollOffsetAndhBoxPadding and setGridWidth
  8308. // and to call the method ONCE after the end of loop below
  8309. // 1) Analyse colModel, colNames properties and sortname parameter to calculate
  8310. // minimal and optimal width of every column and the grid. It could be
  8311. // some important cases which should be
  8312. // a) The current width of the grid is LESS then optimal width and resizable column don't have fixed:true property.
  8313. // 1. save widthOrg of the resizable column in temporary variable
  8314. // 2. set widthOrg property of the resizable column to optimal size and set additionally fixed:true
  8315. // 3. call setGridWidth with the CURRENT grid width to change shrink width of all fixed:false
  8316. p.shrinkToFit = false; // make no shrinking during resizing of any columns
  8317. p.autoResizing.adjustGridWidth = true;
  8318. p.autoResizing.fixWidthOnShrink = false;
  8319. for (iCol = 0; iCol < nCol; iCol++) {
  8320. cm = colModel[iCol];
  8321. if (cm.autoResizable && cm.formatter !== "actions") {
  8322. autoResizeColumn.call($self, iCol, true);
  8323. }
  8324. }
  8325. // finalization
  8326. grid.hDiv.scrollLeft = grid.bDiv.scrollLeft;
  8327. if (p.footerrow) {
  8328. grid.sDiv.scrollLeft = grid.bDiv.scrollLeft;
  8329. }
  8330. self.fixScrollOffsetAndhBoxPadding();
  8331. if (!isNaN(width)) {
  8332. base.setGridWidth.call($self, width, false);
  8333. } else if (adjustGridWidth) {
  8334. base.setGridWidth.call($self, grid.newWidth + p.scrollOffset, false);
  8335. }
  8336. // restore the original shrinkToFit value
  8337. p.autoResizing.fixWidthOnShrink = fixWidthOnShrink;
  8338. p.autoResizing.adjustGridWidth = adjustGridWidth;
  8339. p.shrinkToFit = shrinkToFit;
  8340. });
  8341. }
  8342. });
  8343. // end module grid.base
  8344. /**
  8345. * jqGrid extension for cellediting Grid Data
  8346. * Copyright (c) 2008-2014, Tony Tomov, tony@trirand.com, http://trirand.com/blog/
  8347. * Copyright (c) 2014-2018, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  8348. * Dual licensed under the MIT and GPL licenses:
  8349. * http://www.opensource.org/licenses/mit-license.php
  8350. * http://www.gnu.org/licenses/gpl-2.0.html
  8351. **/
  8352. // begin module grid.celledit
  8353. var getTdByColumnIndex = function (tr, iCol) {
  8354. var $t = this, frozenRows = $t.grid.fbRows;
  8355. tr = frozenRows != null && frozenRows[0].cells.length > iCol ? frozenRows[tr.rowIndex] : tr;
  8356. return tr != null && tr.cells != null ? $(tr.cells[iCol]) : $();
  8357. },
  8358. safeHeightSet = function ($elem, newHeight) {
  8359. var height = $elem.height();
  8360. if (Math.abs(height - newHeight) >= 1 && newHeight > 0) {
  8361. $elem.height(newHeight);
  8362. height = $elem.height();
  8363. if (Math.abs(newHeight - height) >= 1) {
  8364. $elem.height(newHeight + Math.round((newHeight - height)));
  8365. }
  8366. }
  8367. };
  8368. jgrid.extend({
  8369. editCell: function (iRow, iCol, ed) {
  8370. return this.each(function () {
  8371. var $t = this, $self = $($t), p = $t.p, nm, tmp, $td, cm, rows = $t.rows;
  8372. if (!$t.grid || p.cellEdit !== true || rows == null || rows[iRow] == null) {
  8373. return;
  8374. }
  8375. iRow = parseInt(iRow, 10); // we change iRow and rows[iRow] can be change too
  8376. iCol = parseInt(iCol, 10);
  8377. if (isNaN(iRow) || isNaN(iCol)) {
  8378. return;
  8379. }
  8380. var tr = rows[iRow], rowid = tr != null ? tr.id : null, $tr = $(tr), edittype,
  8381. iColOld = parseInt(p.iCol, 10), iRowOld = parseInt(p.iRow, 10),
  8382. $trOld = $(rows[iRowOld]), savedRow = p.savedRow;
  8383. // select the row that can be used for other methods
  8384. if (rowid == null) {
  8385. return;
  8386. }
  8387. p.selrow = rowid;
  8388. if (!p.knv) {
  8389. $self.jqGrid("GridNav");
  8390. }
  8391. // check to see if we have already edited cell
  8392. if (savedRow.length > 0 && $trOld.length > 0) {
  8393. // prevent second click on that field and enable selects
  8394. if (ed === true) {
  8395. if (iRow === iRowOld && iCol === iColOld) {
  8396. return;
  8397. }
  8398. }
  8399. // save the cell
  8400. $self.jqGrid("saveCell", savedRow[0].id, savedRow[0].ic);
  8401. } else {
  8402. setTimeout(function () {
  8403. $("#" + jgrid.jqID(p.knv)).attr("tabindex", "-1").focus();
  8404. }, 1);
  8405. }
  8406. cm = p.colModel[iCol];
  8407. nm = cm.name;
  8408. if (nm === "subgrid" || nm === "cb" || nm === "rn") {
  8409. return;
  8410. }
  8411. $td = getTdByColumnIndex.call($t, tr, iCol);
  8412. var editable = cm.editable, mode = "cell";
  8413. if ($.isFunction(editable)) {
  8414. editable = editable.call($t, {
  8415. rowid: rowid,
  8416. iCol: iCol,
  8417. iRow: iRow,
  8418. cmName: nm,
  8419. cm: cm,
  8420. mode: mode
  8421. });
  8422. }
  8423. var highlightClasses = $self.jqGrid("getGuiStyles", "states.select", "edit-cell"),
  8424. hoverClasses = $self.jqGrid("getGuiStyles", "states.hover", "selected-row");
  8425. if (editable === true && ed === true && !$td.hasClass("not-editable-cell")) {
  8426. if (!p.noCellSelection) {
  8427. if (iColOld >= 0 && iRowOld >= 0) {
  8428. getTdByColumnIndex.call($t, $trOld[0], iColOld).removeClass(highlightClasses);
  8429. $trOld.removeClass(hoverClasses);
  8430. }
  8431. $td.addClass(highlightClasses);
  8432. $tr.addClass(hoverClasses);
  8433. }
  8434. if (!cm.edittype) {
  8435. cm.edittype = "text";
  8436. }
  8437. edittype = cm.edittype;
  8438. try {
  8439. tmp = $.unformat.call($t, $td, { rowId: rowid, colModel: cm }, iCol);
  8440. } catch (ex) {
  8441. tmp = edittype === "textarea" ? $td.text() : $td.html();
  8442. }
  8443. if (p.autoEncodeOnEdit) {
  8444. tmp = jgrid.oldDecodePostedData(tmp);
  8445. }
  8446. if (tmp === "&nbsp;" || tmp === "&#160;" || (tmp.length === 1 && tmp.charCodeAt(0) === 160)) {
  8447. tmp = "";
  8448. }
  8449. if ($.isFunction(p.formatCell)) {
  8450. var tmp2 = p.formatCell.call($t, rowid, nm, tmp, iRow, iCol);
  8451. if (tmp2 !== undefined) {
  8452. tmp = tmp2;
  8453. }
  8454. }
  8455. feedback.call($t, "beforeEditCell", rowid, nm, tmp, iRow, iCol);
  8456. savedRow.push({ id: iRow, ic: iCol, name: nm, v: tmp });
  8457. p.editingInfo[rowid] = {
  8458. mode: "cellEditing",
  8459. savedRow: savedRow[savedRow.length - 1],
  8460. editable: {}
  8461. };
  8462. p.editingInfo[rowid].editable[nm] = editable;
  8463. var opt = $.extend({}, cm.editoptions || {},
  8464. { id: iRow + "_" + nm, name: nm, rowId: rowid, mode: mode, cm: cm, iCol: iCol });
  8465. var elc = jgrid.createEl.call($t, edittype, opt, tmp, true, $.extend({}, jgrid.ajaxOptions, p.ajaxSelectOptions || {})),
  8466. $dataFiled = $td,
  8467. editingColumnWithTreeGridIcon = p.treeGrid === true && nm === p.ExpandColumn;
  8468. if (editingColumnWithTreeGridIcon) {
  8469. $dataFiled = $td.children("span.cell-wrapperleaf,span.cell-wrapper");
  8470. }
  8471. $dataFiled.html("").append(elc).attr("tabindex", "0");
  8472. if (editingColumnWithTreeGridIcon) { // && elc.style.width === "100%"
  8473. $(elc).width($td.width() - $td.children("div.tree-wrap").outerWidth());
  8474. }
  8475. jgrid.bindEv.call($t, elc, opt);
  8476. if (p.frozenColumns && iCol < $self.jqGrid("getNumberOfFrozenColumns")) {
  8477. safeHeightSet($($t.rows[tr.rowIndex].cells[iCol]), $td.height());
  8478. }
  8479. setTimeout(function () {
  8480. $(elc).focus();
  8481. }, 0);
  8482. $("input, select, textarea", $td).on("keydown", function (e) {
  8483. if (e.keyCode === 27) {
  8484. if ($("input.hasDatepicker", $td).length > 0) {
  8485. if ($(".ui-datepicker").is(":hidden")) {
  8486. $self.jqGrid("restoreCell", iRow, iCol);
  8487. } else {
  8488. $("input.hasDatepicker", $td).datepicker("hide");
  8489. }
  8490. } else {
  8491. $self.jqGrid("restoreCell", iRow, iCol);
  8492. }
  8493. } //ESC
  8494. if (e.keyCode === 13 && !e.shiftKey) {
  8495. $self.jqGrid("saveCell", iRow, iCol);
  8496. // Prevent default action
  8497. return false;
  8498. } //Enter
  8499. if (e.keyCode === 9) {
  8500. if (!$t.grid.hDiv.loading) {
  8501. if (e.shiftKey) {
  8502. $self.jqGrid("prevCell", iRow, iCol); //Shift TAb
  8503. } else {
  8504. $self.jqGrid("nextCell", iRow, iCol); //Tab
  8505. }
  8506. } else {
  8507. return false;
  8508. }
  8509. }
  8510. e.stopPropagation();
  8511. });
  8512. feedback.call($t, "afterEditCell", rowid, nm, tmp, iRow, iCol);
  8513. } else {
  8514. if (!p.noCellSelection) {
  8515. if (iColOld >= 0 && iRowOld >= 0) {
  8516. getTdByColumnIndex.call($t, $trOld[0], iColOld).removeClass(highlightClasses);
  8517. $trOld.removeClass(hoverClasses);
  8518. }
  8519. $td.addClass(highlightClasses);
  8520. $tr.addClass(hoverClasses);
  8521. }
  8522. tmp = $td.html().replace(/&#160;/ig, "");
  8523. feedback.call($t, "onSelectCell", rowid, nm, tmp, iRow, iCol);
  8524. }
  8525. p.iCol = iCol;
  8526. p.iRow = iRow;
  8527. });
  8528. },
  8529. saveCell: function (iRow, iCol) {
  8530. return this.each(function () {
  8531. var $t = this, $self = $($t), p = $t.p, grid = $t.grid, infoDialog = jgrid.info_dialog, jqID = jgrid.jqID;
  8532. if (!grid || p.cellEdit !== true) {
  8533. return;
  8534. }
  8535. var errors = $self.jqGrid("getGridRes", "errors"), errcap = errors.errcap,
  8536. edit = $self.jqGrid("getGridRes", "edit"), bClose = edit.bClose,
  8537. savedRow = p.savedRow, fr = savedRow.length >= 1 ? 0 : null;
  8538. if (fr !== null) {
  8539. var tr = $t.rows[iRow], rowid = tr != null ? tr.id : null, $tr = tr != null ? $(tr) : $(), cm = p.colModel[iCol], nm = cm.name, vv,
  8540. $td = getTdByColumnIndex.call($t, tr, iCol), valueText = {},
  8541. v = jgrid.getEditedValue.call($t, $td, cm, valueText);
  8542. // The common approach is if nothing changed do not do anything
  8543. if (v !== savedRow[fr].v) {
  8544. vv = $self.triggerHandler("jqGridBeforeSaveCell", [rowid, nm, v, iRow, iCol]);
  8545. if (vv !== undefined) {
  8546. v = vv;
  8547. }
  8548. if ($.isFunction(p.beforeSaveCell)) {
  8549. vv = p.beforeSaveCell.call($t, rowid, nm, v, iRow, iCol);
  8550. if (vv !== undefined) {
  8551. v = vv;
  8552. }
  8553. }
  8554. var cv = jgrid.checkValues.call($t, v, iCol, undefined, undefined, {
  8555. oldValue: savedRow[fr].v,
  8556. newValue: v,
  8557. cmName: nm,
  8558. rowid: rowid,
  8559. iCol: iCol,
  8560. iRow: iRow,
  8561. cm: cm,
  8562. tr: tr,
  8563. td: $td,
  8564. mode: "cell"
  8565. }),
  8566. formatoptions = cm.formatoptions || {};
  8567. if (cv == null || cv === true || cv[0] === true) {
  8568. var addpost = $self.triggerHandler("jqGridBeforeSubmitCell", [rowid, nm, v, iRow, iCol]) || {};
  8569. if ($.isFunction(p.beforeSubmitCell)) {
  8570. addpost = p.beforeSubmitCell.call($t, rowid, nm, v, iRow, iCol);
  8571. if (!addpost) {
  8572. addpost = {};
  8573. }
  8574. }
  8575. if ($("input.hasDatepicker", $td).length > 0) {
  8576. $("input.hasDatepicker", $td).datepicker("hide");
  8577. }
  8578. if (cm.formatter === "date" && formatoptions.sendFormatted !== true) {
  8579. // TODO: call all other predefined formatters!!! Not only formatter: "date" have the problem.
  8580. // Floating point separator for example
  8581. v = $.unformat.date.call($t, v, cm);
  8582. }
  8583. if (p.cellsubmit === "remote") {
  8584. if (p.cellurl) {
  8585. var postdata = {};
  8586. postdata[nm] = v;
  8587. var opers = p.prmNames, idname = opers.id, oper = opers.oper;
  8588. postdata[idname] = jgrid.stripPref(p.idPrefix, rowid);
  8589. postdata[oper] = opers.editoper;
  8590. postdata = $.extend(addpost, postdata);
  8591. if (p.autoEncodeOnEdit) {
  8592. $.each(postdata, function (n, val) {
  8593. if (!$.isFunction(val)) {
  8594. postdata[n] = jgrid.oldEncodePostedData(val);
  8595. }
  8596. });
  8597. }
  8598. $self.jqGrid("progressBar", { method: "show", loadtype: p.loadui, htmlcontent: $self.jqGrid("getGridRes", "defaults.savetext") || "Saving..." });
  8599. grid.hDiv.loading = true;
  8600. $.ajax($.extend({
  8601. url: $.isFunction(p.cellurl) ? p.cellurl.call($t, p.cellurl, iRow, iCol, rowid, v, nm) : p.cellurl,
  8602. //data :$.isFunction(p.serializeCellData) ? p.serializeCellData.call($t, postdata) : postdata,
  8603. data: jgrid.serializeFeedback.call($t, p.serializeCellData, "jqGridSerializeCellData", postdata),
  8604. type: "POST",
  8605. complete: function (jqXHR) {
  8606. grid.endReq.call($t);
  8607. if ((jqXHR.status < 300 || jqXHR.status === 304) && (jqXHR.status !== 0 || jqXHR.readyState !== 4)) {
  8608. var ret = $self.triggerHandler("jqGridAfterSubmitCell", [$t, jqXHR, postdata.id, nm, v, iRow, iCol]) || [true, ""];
  8609. if (ret === true || (ret[0] === true && $.isFunction(p.afterSubmitCell))) {
  8610. ret = p.afterSubmitCell.call($t, jqXHR, postdata.id, nm, v, iRow, iCol);
  8611. }
  8612. if (ret == null || ret === true || ret[0] === true) {
  8613. $self.jqGrid("setCell", rowid, iCol, v, false, false, true);
  8614. $td.addClass("dirty-cell");
  8615. $tr.addClass("edited");
  8616. feedback.call($t, "afterSaveCell", rowid, nm, v, iRow, iCol);
  8617. savedRow.splice(0, 1);
  8618. delete p.editingInfo[rowid];
  8619. } else {
  8620. infoDialog.call($t, errcap, ret[1], bClose);
  8621. $self.jqGrid("restoreCell", iRow, iCol);
  8622. }
  8623. }
  8624. },
  8625. error: function (jqXHR, textStatus, errorThrown) {
  8626. $self.triggerHandler("jqGridErrorCell", [jqXHR, textStatus, errorThrown]);
  8627. if ($.isFunction(p.errorCell)) {
  8628. p.errorCell.call($t, jqXHR, textStatus, errorThrown);
  8629. $self.jqGrid("restoreCell", iRow, iCol);
  8630. } else {
  8631. infoDialog.call($t, errcap, jqXHR.status + " : " + jqXHR.statusText + "<br/>" + textStatus, bClose);
  8632. $self.jqGrid("restoreCell", iRow, iCol);
  8633. }
  8634. }
  8635. }, jgrid.ajaxOptions, p.ajaxCellOptions || {}));
  8636. } else {
  8637. try {
  8638. infoDialog.call($t, errcap, errors.nourl, bClose);
  8639. $self.jqGrid("restoreCell", iRow, iCol);
  8640. } catch (ignore) { }
  8641. }
  8642. }
  8643. if (p.cellsubmit === "clientArray") {
  8644. $self.jqGrid("setCell", rowid, iCol,
  8645. cm.edittype === "select" && cm.formatter !== "select" ? valueText.text : v,
  8646. false, false, true);
  8647. $td.addClass("dirty-cell");
  8648. $tr.addClass("edited");
  8649. feedback.call($t, "afterSaveCell", rowid, nm, v, iRow, iCol);
  8650. if (p.frozenColumns && iCol < $self.jqGrid("getNumberOfFrozenColumns")) {
  8651. try {
  8652. $t.rows[tr.rowIndex].cells[iCol].style.height = "";
  8653. } catch (ignore) { }
  8654. }
  8655. savedRow.splice(0, 1);
  8656. delete p.editingInfo[rowid];
  8657. }
  8658. } else {
  8659. try {
  8660. setTimeout(function () {
  8661. var relativeRect = jgrid.getRelativeRect.call($t, $td);
  8662. infoDialog.call($t, errcap, v + " " + cv[1], bClose, {
  8663. top: relativeRect.top,
  8664. left: relativeRect.left + $($t).closest(".ui-jqgrid").offset().left
  8665. });
  8666. }, 50);
  8667. $self.jqGrid("restoreCell", iRow, iCol);
  8668. } catch (ignore) { }
  8669. }
  8670. } else {
  8671. $self.jqGrid("restoreCell", iRow, iCol);
  8672. }
  8673. }
  8674. setTimeout(function () {
  8675. $("#" + jqID(p.knv)).attr("tabindex", "-1").focus();
  8676. }, 0);
  8677. });
  8678. },
  8679. restoreCell: function (iRow, iCol) {
  8680. return this.each(function () {
  8681. var $t = this, p = $t.p, tr = $t.rows[iRow], rowid = tr.id, v, cm, formatoptions;
  8682. if (!$t.grid || p.cellEdit !== true) {
  8683. return;
  8684. }
  8685. var savedRow = p.savedRow, $td = getTdByColumnIndex.call($t, tr, iCol);
  8686. if (savedRow.length >= 1) {
  8687. // datepicker fix
  8688. if ($.isFunction($.fn.datepicker)) {
  8689. try {
  8690. $("input.hasDatepicker", $td).datepicker("hide");
  8691. } catch (ignore) { }
  8692. }
  8693. cm = p.colModel[iCol];
  8694. if (p.treeGrid === true && cm != null && cm.name === p.ExpandColumn) {
  8695. $td.children("span.cell-wrapperleaf,span.cell-wrapper").empty();
  8696. } else {
  8697. $td.empty();
  8698. }
  8699. $td.attr("tabindex", "-1");
  8700. v = savedRow[0].v;
  8701. if (cm != null) {
  8702. formatoptions = cm.formatoptions || {};
  8703. if (cm.formatter === "date" && formatoptions.sendFormatted !== true) {
  8704. // TODO: call all other predefined formatters!!! Not only formatter: "date" have the problem.
  8705. // Floating point separator for example
  8706. v = $.unformat.date.call($t, v, cm);
  8707. }
  8708. $($t).jqGrid("setCell", rowid, iCol, v, false, false, true);
  8709. if (p.frozenColumns && iCol < $($t).jqGrid("getNumberOfFrozenColumns")) {
  8710. try {
  8711. $t.rows[tr.rowIndex].cells[iCol].style.height = "";
  8712. } catch (ignore) { }
  8713. }
  8714. }
  8715. feedback.call($t, "afterRestoreCell", rowid, v, iRow, iCol);
  8716. savedRow.splice(0, 1);
  8717. delete p.editingInfo[rowid];
  8718. }
  8719. setTimeout(function () {
  8720. $("#" + p.knv).attr("tabindex", "-1").focus();
  8721. }, 0);
  8722. });
  8723. },
  8724. nextCell: function (iRow, iCol) {
  8725. return this.each(function () {
  8726. var $t = this, $self = $($t), p = $t.p, nCol = false, i, editable, cm, rows = $t.rows;
  8727. if (!$t.grid || p.cellEdit !== true || rows == null || rows[iRow] == null) {
  8728. return;
  8729. }
  8730. // try to find next editable cell
  8731. for (i = iCol + 1; i < p.colModel.length; i++) {
  8732. cm = p.colModel[i];
  8733. editable = cm.editable;
  8734. if ($.isFunction(editable)) {
  8735. editable = editable.call($t, {
  8736. rowid: rows[iRow].id,
  8737. iCol: i,
  8738. iRow: iRow,
  8739. cmName: cm.name,
  8740. cm: cm,
  8741. mode: "cell"
  8742. });
  8743. }
  8744. if (editable === true) {
  8745. nCol = i;
  8746. break;
  8747. }
  8748. }
  8749. if (nCol !== false) {
  8750. $self.jqGrid("editCell", iRow, nCol, true);
  8751. } else {
  8752. if (p.savedRow.length > 0) {
  8753. $self.jqGrid("saveCell", iRow, iCol);
  8754. }
  8755. }
  8756. });
  8757. },
  8758. prevCell: function (iRow, iCol) {
  8759. return this.each(function () {
  8760. var $t = this, $self = $($t), p = $t.p, nCol = false, i, editable, cm, rows = $t.rows;
  8761. if (!$t.grid || p.cellEdit !== true || rows == null || rows[iRow] == null) {
  8762. return;
  8763. }
  8764. // try to find next editable cell
  8765. for (i = iCol - 1; i >= 0; i--) {
  8766. cm = p.colModel[i];
  8767. editable = cm.editable;
  8768. if ($.isFunction(editable)) {
  8769. editable = editable.call($t, {
  8770. rowid: rows[iRow].id,
  8771. iCol: i,
  8772. iRow: iRow,
  8773. cmName: cm.name,
  8774. cm: cm,
  8775. mode: "cell"
  8776. });
  8777. }
  8778. if (editable === true) {
  8779. nCol = i;
  8780. break;
  8781. }
  8782. }
  8783. if (nCol !== false) {
  8784. $self.jqGrid("editCell", iRow, nCol, true);
  8785. } else {
  8786. if (p.savedRow.length > 0) {
  8787. $self.jqGrid("saveCell", iRow, iCol);
  8788. }
  8789. }
  8790. });
  8791. },
  8792. GridNav: function () {
  8793. return this.each(function () {
  8794. var $t = this, $self = $($t), p = $t.p, grid = $t.grid, i, kdir;
  8795. if (!grid || p.cellEdit !== true) {
  8796. return;
  8797. }
  8798. var bDiv = grid.bDiv;
  8799. // trick to process keydown on non input elements
  8800. p.knv = p.id + "_kn";
  8801. var selection = $("<div style='position:fixed;top:0px;width:1px;height:1px;' tabindex='0'><div tabindex='-1' style='width:1px;height:1px;' id='" + p.knv + "'></div></div>");
  8802. function scrollGrid(iR, iC, tp) {
  8803. var tr = $t.rows[iR];
  8804. if (tp.substr(0, 1) === "v") {
  8805. var ch = bDiv.clientHeight,
  8806. st = bDiv.scrollTop,
  8807. nRot = tr.offsetTop + tr.clientHeight,
  8808. pRot = tr.offsetTop;
  8809. if (tp === "vd") {
  8810. if (nRot >= st + ch) {
  8811. bDiv.scrollTop = bDiv.scrollTop + tr.clientHeight;
  8812. }
  8813. }
  8814. if (tp === "vu") {
  8815. if (pRot < st) {
  8816. bDiv.scrollTop = bDiv.scrollTop - tr.clientHeight;
  8817. }
  8818. }
  8819. }
  8820. if (tp === "h") {
  8821. var cw = bDiv.clientWidth,
  8822. sl = bDiv.scrollLeft,
  8823. td = tr.cells[iC],
  8824. nCol = td.offsetLeft + td.clientWidth,
  8825. pCol = td.offsetLeft;
  8826. if (nCol >= cw + parseInt(sl, 10)) {
  8827. bDiv.scrollLeft = bDiv.scrollLeft + td.clientWidth;
  8828. } else if (pCol < sl) {
  8829. bDiv.scrollLeft = bDiv.scrollLeft - td.clientWidth;
  8830. }
  8831. }
  8832. }
  8833. function findNextVisible(iC, act) {
  8834. var ind = 0, j, colModel = p.colModel;
  8835. if (act === "lft") {
  8836. ind = iC + 1;
  8837. for (j = iC; j >= 0; j--) {
  8838. if (colModel[j].hidden !== true) {
  8839. ind = j;
  8840. break;
  8841. }
  8842. }
  8843. }
  8844. if (act === "rgt") {
  8845. ind = iC - 1;
  8846. for (j = iC; j < colModel.length; j++) {
  8847. if (colModel[j].hidden !== true) {
  8848. ind = j;
  8849. break;
  8850. }
  8851. }
  8852. }
  8853. return ind;
  8854. }
  8855. $(selection).insertBefore(grid.cDiv);
  8856. $("#" + p.knv)
  8857. .focus()
  8858. .keydown(function (e) {
  8859. var iRowOld = parseInt(p.iRow, 10), iColOld = parseInt(p.iCol, 10);
  8860. kdir = e.keyCode;
  8861. if (p.direction === "rtl") {
  8862. if (kdir === 37) {
  8863. kdir = 39;
  8864. } else if (kdir === 39) {
  8865. kdir = 37;
  8866. }
  8867. }
  8868. switch (kdir) {
  8869. case 38:
  8870. if (iRowOld - 1 > 0) {
  8871. scrollGrid(iRowOld - 1, iColOld, "vu");
  8872. $self.jqGrid("editCell", iRowOld - 1, iColOld, false);
  8873. }
  8874. break;
  8875. case 40:
  8876. if (iRowOld + 1 <= $t.rows.length - 1) {
  8877. scrollGrid(iRowOld + 1, iColOld, "vd");
  8878. $self.jqGrid("editCell", iRowOld + 1, iColOld, false);
  8879. }
  8880. break;
  8881. case 37:
  8882. if (iColOld - 1 >= 0) {
  8883. i = findNextVisible(iColOld - 1, "lft");
  8884. scrollGrid(iRowOld, i, "h");
  8885. $self.jqGrid("editCell", iRowOld, i, false);
  8886. }
  8887. break;
  8888. case 39:
  8889. if (iColOld + 1 <= p.colModel.length - 1) {
  8890. i = findNextVisible(iColOld + 1, "rgt");
  8891. scrollGrid(iRowOld, i, "h");
  8892. $self.jqGrid("editCell", iRowOld, i, false);
  8893. }
  8894. break;
  8895. case 13:
  8896. if (iColOld >= 0 && iRowOld >= 0) {
  8897. $self.jqGrid("editCell", iRowOld, iColOld, true);
  8898. }
  8899. break;
  8900. default:
  8901. return true;
  8902. }
  8903. return false;
  8904. });
  8905. });
  8906. },
  8907. getChangedCells: function (mthd) {
  8908. var ret = [];
  8909. if (!mthd) {
  8910. mthd = "all";
  8911. }
  8912. this.each(function () {
  8913. var $t = this, p = $t.p, htmlDecode = jgrid.htmlDecode, rows = $t.rows;
  8914. if (!$t.grid || p.cellEdit !== true) {
  8915. return;
  8916. }
  8917. $(rows).each(function (j) {
  8918. var res = {};
  8919. if ($(this).hasClass("edited")) {
  8920. var tr = this;
  8921. $(this.cells).each(function (i) {
  8922. var cm = p.colModel[i], nm = cm.name, $td = getTdByColumnIndex.call($t, tr, i); // $td = $(this);
  8923. if (nm !== "cb" && nm !== "subgrid" && nm !== "rn" && (mthd !== "dirty" || $td.hasClass("dirty-cell"))) {
  8924. try {
  8925. res[nm] = $.unformat.call($t, $td[0], { rowId: rows[j].id, colModel: cm }, i);
  8926. } catch (e) {
  8927. res[nm] = htmlDecode($td.html());
  8928. }
  8929. }
  8930. });
  8931. res.id = this.id;
  8932. ret.push(res);
  8933. }
  8934. });
  8935. });
  8936. return ret;
  8937. }
  8938. });
  8939. // end module grid.celledit
  8940. /**
  8941. * jqGrid common function
  8942. * Tony Tomov tony@trirand.com, http://trirand.com/blog/
  8943. * Changed by Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  8944. * Dual licensed under the MIT and GPL licenses:
  8945. * http://www.opensource.org/licenses/mit-license.php
  8946. * http://www.gnu.org/licenses/gpl-2.0.html
  8947. */
  8948. // begin module grid.common
  8949. var getGuiStyles = base.getGuiStyles, getGridRes = base.getGridRes;
  8950. jgrid.jqModal = jgrid.jqModal || {};
  8951. $.extend(true, jgrid.jqModal, { toTop: true });
  8952. $.extend(jgrid, {
  8953. // Modal functions
  8954. // The methods showModal and closeModal will be used as callback of $.jqm jQuery plugin defined in jqModal.js
  8955. // The modul can support multiple modal dialods. It hold the information about evety active modules in internal array of "hashes".
  8956. // The modal dialogs as hidden typically. Before the dialog will be visible onShow callback (showModal) will be called.
  8957. //
  8958. // Every eleement contains "hash object" which have 4 properties:
  8959. // w: (jQuery object) The modal element, represent the outer div of the modal dialog
  8960. // o: (jQuery object) The overlay element. It will be assigned on the first opening of the modal
  8961. // c: (object) The modal's options object. The options used durin creating the modal.
  8962. // One can use global $.jgrid.jqModal or gris specifif p.jqModal to specify defaults of the options.
  8963. // t: (DOM object) The triggering element.
  8964. // s: numeric part of "id" used for modal dialog. The modal dialog have class "jqmID" + s.
  8965. // a: Boolean. It's false initially. It will be set to true during opening and will set to false on closing.
  8966. showModal: function (h) {
  8967. // w: (jQuery object) The modal element
  8968. h.w.show();
  8969. },
  8970. closeModal: function (h) {
  8971. // w: (jQuery object) The modal element
  8972. // o: (jQuery object) The overlay element
  8973. // c: (object) The modal's options object
  8974. h.w.hide().attr("aria-hidden", "true");
  8975. if (h.o) {
  8976. h.o.remove();
  8977. }
  8978. },
  8979. hideModal: function (selector, o) {
  8980. o = $.extend({ jqm: true, gb: "", removemodal: false }, o || {});
  8981. var thisgrid = o.gb && typeof o.gb === "string" && o.gb.substr(0, 6) === "#gbox_" ? $("#" + o.gb.substr(6))[0] : false,
  8982. $selector = $(selector);
  8983. if (o.onClose) {
  8984. var oncret = thisgrid ? o.onClose.call(thisgrid, selector) : o.onClose(selector);
  8985. if (typeof oncret === "boolean" && !oncret) { return; }
  8986. }
  8987. if ($.fn.jqm && o.jqm === true) {
  8988. $selector.attr("aria-hidden", "true").jqmHide();
  8989. } else {
  8990. if (o.gb !== "") {
  8991. try { $(">.jqgrid-overlay", o.gb).first().hide(); } catch (ignore) { }
  8992. }
  8993. $selector.hide().attr("aria-hidden", "true");
  8994. }
  8995. if (o.removemodal) {
  8996. $selector.remove();
  8997. }
  8998. },
  8999. //Helper functions
  9000. createModal: function (aIDs, content, o, insertSelector, posSelector, appendsel, css) {
  9001. var jqID = jgrid.jqID, p = this.p;
  9002. o = $.extend(true, {
  9003. resizingRightBottomIcon: base.getIconRes.call(this, "form.resizableLtr")
  9004. }, jgrid.jqModal || {},
  9005. p != null ? p.jqModal || {} : {},
  9006. o);
  9007. // create main window "div.ui-jqdialog", which will contains other components of the modal window:
  9008. // "div.ui-jqdialog-titlebar", "div.ui-jqdialog-content" and optionally resizer like "div.jqResize"
  9009. var mw = document.createElement("div"), themodalSelector = "#" + jqID(aIDs.themodal),
  9010. rtlsup = $(o.gbox).attr("dir") === "rtl" ? true : false,
  9011. resizeAlso = aIDs.resizeAlso ? "#" + jqID(aIDs.resizeAlso) : false;
  9012. css = $.extend({}, css || {});
  9013. mw.className = getGuiStyles.call(this, "dialog.window", "ui-jqdialog");
  9014. mw.id = aIDs.themodal;
  9015. mw.dir = rtlsup ? "rtl" : "ltr";
  9016. var mdoc = document.createElement("div");
  9017. mdoc.className = getGuiStyles.call(this, "dialog.document");
  9018. $(mdoc).attr("role", "document");
  9019. var msubdoc = document.createElement("div");
  9020. msubdoc.className = getGuiStyles.call(this, "dialog.subdocument");
  9021. mdoc.appendChild(msubdoc);
  9022. mw.appendChild(mdoc);
  9023. // create the title "div.ui-jqdialog-titlebar", which contains:
  9024. // "span.ui-jqdialog-title" with the title text and "a.ui-jqdialog-titlebar-close" with the closing button
  9025. var mh = document.createElement("div");
  9026. mh.className = getGuiStyles.call(this,
  9027. "dialog.header",
  9028. "ui-jqdialog-titlebar " + (rtlsup ? "ui-jqdialog-titlebar-rtl" : "ui-jqdialog-titlebar-ltr"));
  9029. mh.id = aIDs.modalhead;
  9030. $(mh).append("<span class='ui-jqdialog-title'>" + o.caption + "</span>");
  9031. var hoverClasses = getGuiStyles.call(this, "states.hover"),
  9032. ahr = $("<a aria-label='Close' class='" + getGuiStyles.call(this, "dialog.closeButton", "ui-jqdialog-titlebar-close") + "'></a>")
  9033. .hover(function () { ahr.addClass(hoverClasses); },
  9034. function () { ahr.removeClass(hoverClasses); })
  9035. .append("<span class='" + base.getIconRes.call(this, "form.close") + "'></span>");
  9036. $(mh).append(ahr);
  9037. // create "div.ui-jqdialog-content" which hold some HTML content (see input parameter)
  9038. var mc = document.createElement("div");
  9039. $(mc).addClass(getGuiStyles.call(this, "dialog.content", "ui-jqdialog-content"))
  9040. .attr("id", aIDs.modalcontent);
  9041. $(mc).append(content);
  9042. // place "div.ui-jqdialog-content" and "div.ui-jqdialog-titlebar" in main window "div.ui-jqdialog"
  9043. msubdoc.appendChild(mc);
  9044. $(msubdoc).prepend(mh);
  9045. // appendsel and insertSelector specifies where the dialog should be placed on the HTML page
  9046. if (appendsel === true) {
  9047. $("body").append(mw); //append as first child in body -for alert dialog
  9048. } else if (typeof appendsel === "string") {
  9049. $(appendsel).append(mw);
  9050. } else { $(mw).insertBefore(insertSelector); }
  9051. $(mw).css(css);
  9052. if (o.jqModal === undefined) { o.jqModal = true; } // internal use
  9053. var coord = {};
  9054. if ($.fn.jqm && o.jqModal === true) {
  9055. if (o.left === 0 && o.top === 0 && o.overlay) {
  9056. o = $(posSelector).offset();
  9057. o.left += 4;
  9058. o.top += 4;
  9059. }
  9060. coord.top = o.top + "px";
  9061. coord.left = o.left;
  9062. } else if (o.left !== 0 || o.top !== 0) {
  9063. coord.left = o.left;
  9064. coord.top = o.top + "px";
  9065. }
  9066. $("a.ui-jqdialog-titlebar-close", mh).click(function () {
  9067. var oncm = $(themodalSelector).data("onClose") || o.onClose;
  9068. var gboxclose = $(themodalSelector).data("gbox") || o.gbox;
  9069. jgrid.hideModal(themodalSelector, {
  9070. gb: gboxclose,
  9071. jqm: o.jqModal,
  9072. onClose: oncm,
  9073. removemodal: o.removemodal || false
  9074. });
  9075. return false;
  9076. });
  9077. if (o.width === 0 || !o.width) { o.width = 300; }
  9078. if (o.height === 0 || !o.height) { o.height = 200; }
  9079. if (!o.zIndex) {
  9080. var parentZ = $(insertSelector).parents("*[role=dialog]").first().css("z-index");
  9081. if (parentZ) {
  9082. o.zIndex = parseInt(parentZ, 10) + 2;
  9083. o.toTop = true;
  9084. } else {
  9085. o.zIndex = 950;
  9086. }
  9087. }
  9088. // ONE NEEDS correction of left position in case of RTL, but the current code places
  9089. // modal dialog OUT OF visible part of/ the window if <body dir="rtl">.
  9090. // Thus first of all the lines are commented. Later the FIXED code below will be included.
  9091. /*var rtlt = 0;
  9092. if( rtlsup && coord.left && !appendsel) {
  9093. rtlt = $(o.gbox).width()- (!isNaN(o.width) ? parseInt(o.width,10) :0) - 8; // to do
  9094. // just in case
  9095. coord.left = parseInt(coord.left,10) + parseInt(rtlt,10);
  9096. }*/
  9097. if (coord.left) { coord.left += "px"; }
  9098. $(mw).css($.extend({
  9099. width: isNaN(o.width) ? "auto" : o.width + "px",
  9100. height: isNaN(o.height) ? "auto" : o.height + "px",
  9101. zIndex: o.zIndex
  9102. }, coord))
  9103. .attr({ tabIndex: "-1", "role": "dialog", "aria-labelledby": aIDs.modalhead, "aria-hidden": "true" });
  9104. if (o.drag === undefined) { o.drag = true; }
  9105. if (o.resize === undefined) { o.resize = true; }
  9106. if (o.drag) {
  9107. if ($.fn.jqDrag) {
  9108. // .ui-draggable .ui-dialog-titlebar {cursor: move}
  9109. //$(mw).addClass("ui-draggable"); //css("cursor", "move");
  9110. $(mh).css("cursor", "move");
  9111. $(mw).jqDrag(mh);
  9112. } else {
  9113. try {
  9114. $(mw).draggable({ handle: $("#" + jqID(mh.id)) });
  9115. } catch (ignore) { }
  9116. }
  9117. }
  9118. if (o.resize) {
  9119. if ($.fn.jqResize) {
  9120. $(mc).append("<div class='jqResize ui-resizable-handle ui-resizable-se " + o.resizingRightBottomIcon + "'></div>");
  9121. $(themodalSelector).jqResize(".jqResize", resizeAlso);
  9122. } else {
  9123. try {
  9124. $(mw).resizable({ handles: "se, sw", alsoResize: resizeAlso });
  9125. } catch (ignore) { }
  9126. }
  9127. }
  9128. if (o.closeOnEscape === true) {
  9129. $(mw).keydown(function (e) {
  9130. if (e.which === 27) {
  9131. var cone = $(themodalSelector).data("onClose") || o.onClose;
  9132. jgrid.hideModal(themodalSelector, { gb: o.gbox, jqm: o.jqModal, onClose: cone, removemodal: o.removemodal || false, formprop: !o.recreateForm || false, form: o.form || "" });
  9133. }
  9134. });
  9135. }
  9136. },
  9137. viewModal: function (selector, o) {
  9138. o = $.extend(true, {
  9139. //toTop: false,
  9140. overlay: 30,
  9141. modal: false,
  9142. overlayClass: getGuiStyles.call(this, "overlay"), // "ui-widget-overlay"
  9143. onShow: jgrid.showModal,
  9144. onHide: jgrid.closeModal,
  9145. gbox: "",
  9146. jqm: true,
  9147. jqM: true
  9148. }, jgrid.jqModal || {}, o || {});
  9149. if ($.fn.jqm && o.jqm === true) {
  9150. if (o.jqM) {
  9151. $(selector).attr("aria-hidden", "false").jqm(o).jqmShow();
  9152. } else {
  9153. $(selector).attr("aria-hidden", "false").jqmShow();
  9154. }
  9155. } else {
  9156. if (o.gbox !== "") {
  9157. $(">.jqgrid-overlay", o.gbox).first().show();
  9158. $(selector).data("gbox", o.gbox);
  9159. }
  9160. $(selector).show().attr("aria-hidden", "false");
  9161. try { $(":input:visible", selector)[0].focus(); } catch (ignore) { }
  9162. }
  9163. },
  9164. info_dialog: function (caption, content, closeButtonText, modalopt) {
  9165. var $t = this, p = $t.p,
  9166. mopt = $.extend(true,
  9167. {
  9168. width: 290,
  9169. height: "auto",
  9170. dataheight: "auto",
  9171. drag: true,
  9172. resize: false,
  9173. left: 250,
  9174. top: 170,
  9175. zIndex: 1000,
  9176. jqModal: true,
  9177. modal: false,
  9178. closeOnEscape: true,
  9179. align: "center",
  9180. buttonalign: "center",
  9181. buttons: []
  9182. // {text:"textbutt", id:"buttid", onClick : function(){...}}
  9183. // if the id is not provided we set it like info_button_+ the index in the array - i.e info_button_0,info_button_1...
  9184. },
  9185. jgrid.jqModal || {},
  9186. p != null ? p.jqModal || {} : {},
  9187. { caption: "<b>" + caption + "</b>" },
  9188. modalopt || {}),
  9189. jm = mopt.jqModal;
  9190. if ($.fn.jqm && !jm) { jm = false; }
  9191. // in case there is no jqModal
  9192. var buttstr = "", i, hoverClasses = getGuiStyles.call($t, "states.hover");
  9193. if (mopt.buttons.length > 0) {
  9194. for (i = 0; i < mopt.buttons.length; i++) {
  9195. if (mopt.buttons[i].id === undefined) { mopt.buttons[i].id = "info_button_" + i; }
  9196. buttstr += jgrid.builderFmButon.call($t, mopt.buttons[i].id, mopt.buttons[i].text);
  9197. }
  9198. }
  9199. var dh = isNaN(mopt.dataheight) ? mopt.dataheight : mopt.dataheight + "px",
  9200. cn = "text-align:" + mopt.align + ";",
  9201. $dlg = $("#info_dialog"),
  9202. cnt = "<div id='info_id'>";
  9203. cnt += "<div id='infocnt' style='margin:0px;padding-bottom:1em;width:100%;overflow:auto;position:relative;height:" + dh + ";" + cn + "'>" + content + "</div>";
  9204. if (closeButtonText || buttstr !== "") {
  9205. cnt += "<hr class='" + getGuiStyles.call($t, "dialog.hr") + "' style='margin:1px'/><div style='text-align:" + mopt.buttonalign +
  9206. ";padding:.8em 0 .5em 0;background-image:none;border-width: 1px 0 0 0;'>" +
  9207. (closeButtonText ? jgrid.builderFmButon.call($t, "closedialog", closeButtonText) : "") + buttstr + "</div>";
  9208. }
  9209. cnt += "</div>";
  9210. try {
  9211. if ($dlg.attr("aria-hidden") === "false") {
  9212. jgrid.hideModal("#info_dialog", { jqm: jm });
  9213. }
  9214. $dlg.remove();
  9215. } catch (ignore) { }
  9216. jgrid.createModal.call($t,
  9217. {
  9218. themodal: "info_dialog",
  9219. modalhead: "info_head",
  9220. modalcontent: "info_content",
  9221. resizeAlso: "infocnt"
  9222. },
  9223. cnt,
  9224. mopt,
  9225. "", "", true);
  9226. // attach onclick after inserting into the dom
  9227. $dlg = $("#info_dialog");
  9228. if (buttstr) {
  9229. $.each(mopt.buttons, function () {
  9230. $("#" + jgrid.jqID(this.id), "#info_id")
  9231. .on("click",
  9232. { click: this.onClick },
  9233. function (e) {
  9234. if ($.isFunction(e.data.click)) {
  9235. e.data.click.call($t, e, $dlg);
  9236. }
  9237. return false;
  9238. });
  9239. });
  9240. }
  9241. $("#closedialog", "#info_id").click(function () {
  9242. jgrid.hideModal("#info_dialog", {
  9243. jqm: jm,
  9244. onClose: $dlg.data("onClose") || mopt.onClose,
  9245. gb: $dlg.data("gbox") || mopt.gbox
  9246. });
  9247. return false;
  9248. });
  9249. $(".fm-button", "#info_dialog").hover(
  9250. function () { $(this).addClass(hoverClasses); },
  9251. function () { $(this).removeClass(hoverClasses); }
  9252. );
  9253. if ($.isFunction(mopt.beforeOpen)) { mopt.beforeOpen(); }
  9254. jgrid.viewModal.call($t, "#info_dialog", {
  9255. onHide: function (h) {
  9256. h.w.hide().remove();
  9257. if (h.o) { h.o.remove(); }
  9258. },
  9259. modal: mopt.modal,
  9260. jqm: jm
  9261. });
  9262. if ($.isFunction(mopt.afterOpen)) { mopt.afterOpen(); }
  9263. try { $dlg.focus(); } catch (ignore) { }
  9264. },
  9265. bindEv: function (el, opt) {
  9266. var $t = this, p = $t.p;
  9267. if ($.isFunction(opt.dataInit)) {
  9268. opt.dataInit.call($t, el, opt);
  9269. }
  9270. if (opt.dataEvents) {
  9271. $.each(opt.dataEvents, function () {
  9272. var data = this.data === undefined ?
  9273. $.extend({ gridId: p.id, gridIdSel: p.idSel }, opt) :
  9274. (typeof this.data === "object" && this.data !== null ?
  9275. $.extend(true, { gridId: p.id, gridIdSel: p.idSel }, opt, this.data) :
  9276. this.data);
  9277. $(el).on(this.type, data, this.fn);
  9278. });
  9279. }
  9280. },
  9281. // Form Functions
  9282. createEl: function (eltype, options, vl, autowidth, ajaxso) {
  9283. var elem = "", $t = this, p = $t.p, infoDialog = jgrid.info_dialog,
  9284. getRes = function (path) { return getGridRes.call($($t), path); },
  9285. errcap = getRes("errors.errcap"), edit = getRes("edit"), editMsg = edit.msg, bClose = edit.bClose;
  9286. function setAttributes(elm, atr, exl) {
  9287. var exclude = [
  9288. "dataInit",
  9289. "dataEvents",
  9290. "dataUrl",
  9291. "buildSelect",
  9292. "sopt",
  9293. "searchhidden",
  9294. "defaultValue",
  9295. "attr",
  9296. "custom_element",
  9297. "custom_value",
  9298. "generateValue",
  9299. "postData",
  9300. "selectFilled",
  9301. "rowId",
  9302. "column",
  9303. "mode",
  9304. "cm",
  9305. "iCol"
  9306. ];
  9307. if (exl !== undefined && $.isArray(exl)) {
  9308. $.merge(exclude, exl);
  9309. }
  9310. $.each(atr, function (attrName, value) {
  9311. if ($.inArray(attrName, exclude) === -1) {
  9312. $(elm).attr(attrName, value);
  9313. }
  9314. });
  9315. if (!atr.hasOwnProperty("id")) {
  9316. $(elm).attr("id", jgrid.randId());
  9317. }
  9318. }
  9319. if (options == null) { return ""; }
  9320. switch (eltype) {
  9321. case "textarea":
  9322. elem = document.createElement("textarea");
  9323. if (autowidth) {
  9324. if (!options.cols) { $(elem).css({ width: "100%", "box-sizing": "border-box" }); }
  9325. } else if (!options.cols) { options.cols = 19; }
  9326. if (!options.rows) { options.rows = 2; }
  9327. if (vl === "&nbsp;" || vl === "&#160;" || (vl.length === 1 && vl.charCodeAt(0) === 160)) { vl = ""; }
  9328. elem.value = vl;
  9329. setAttributes(elem, options);
  9330. $(elem).attr({ role: "textbox" }); // , "multiline": "true"
  9331. break;
  9332. case "checkbox": //what code for simple checkbox
  9333. elem = document.createElement("input");
  9334. elem.type = "checkbox";
  9335. if (vl === "" || vl == null) {
  9336. vl = !options.hasOwnProperty("defaultValue") ?
  9337. "false" :
  9338. $.isFunction(options.defaultValue) ?
  9339. options.defaultValue.call($t, {
  9340. cellValue: vl,
  9341. options: options
  9342. }) :
  9343. options.defaultValue;
  9344. }
  9345. if (!options.value) {
  9346. var vl1 = String(vl).toLowerCase();
  9347. if (vl1.search(/(false|f|0|no|n|off|undefined)/i) < 0 && vl1 !== "") {
  9348. elem.checked = true;
  9349. elem.defaultChecked = true;
  9350. elem.value = vl;
  9351. } else {
  9352. elem.value = "on";
  9353. }
  9354. $(elem).data("offval", "off");
  9355. } else {
  9356. var cbval = options.value.split(":");
  9357. if (vl === cbval[0]) {
  9358. elem.checked = true;
  9359. elem.defaultChecked = true;
  9360. }
  9361. elem.value = vl;
  9362. $(elem).data("offval", cbval[1]);
  9363. }
  9364. setAttributes(elem, options, ["value"]);
  9365. $(elem).attr({ role: "checkbox", "aria-checked": elem.checked ? "true" : "false" });
  9366. break;
  9367. case "select":
  9368. elem = document.createElement("select");
  9369. //var msl, ovm = [], isSelected, rowid = null;
  9370. var msl, ovm = [], rowid = null;
  9371. if (options.multiple === true || options.multiple === "multiple") {
  9372. msl = true;
  9373. elem.multiple = "multiple";
  9374. $(elem).attr("aria-multiselectable", "true");
  9375. ovm = vl.split(",");
  9376. ovm = $.map(ovm, function (n) { return $.trim(n); });
  9377. } else {
  9378. msl = false;
  9379. ovm[0] = $.trim(vl);
  9380. }
  9381. if (options.size === undefined) {
  9382. options.size = msl ? 3 : 1;
  9383. }
  9384. try {
  9385. rowid = options.rowId;
  9386. } catch (ignore) { }
  9387. if (p && p.idPrefix) {
  9388. rowid = jgrid.stripPref(p.idPrefix, rowid);
  9389. }
  9390. if (options.dataUrl === undefined && options.generateValue && p.indexByColumnData[options.cm.name] != null) {
  9391. options.value = $t.generateValueFromColumnIndex(options.cm.name, options.separator, options.delimiter);
  9392. }
  9393. if (options.dataUrl !== undefined) {
  9394. var postData = options.postData || ajaxso.postData,
  9395. ajaxContext = {
  9396. elem: elem,
  9397. options: options,
  9398. cm: options.cm,
  9399. mode: options.mode,
  9400. rowid: rowid,
  9401. iCol: options.iCol,
  9402. ovm: ovm
  9403. };
  9404. setAttributes(elem, options, postData ? ["postData"] : undefined);
  9405. $.ajax($.extend({
  9406. url: $.isFunction(options.dataUrl) ? options.dataUrl.call($t, rowid, vl, String(options.name), ajaxContext) : options.dataUrl,
  9407. type: "GET",
  9408. dataType: "html",
  9409. data: $.isFunction(postData) ? postData.call($t, rowid, vl, String(options.name)) : postData,
  9410. context: ajaxContext,
  9411. success: function (data, textStatus, jqXHR) {
  9412. var ovm1 = this.ovm, elem1 = this.elem, cm1 = this.cm, iCol1 = this.iCol,
  9413. options1 = $.extend({}, this.options), rowid1 = this.rowid, mode1 = this.mode,
  9414. a = $.isFunction(options1.buildSelect) ? options1.buildSelect.call($t, data, jqXHR, cm1, iCol1) : data;
  9415. if (typeof a === "string") {
  9416. a = $($.trim(a)).html();
  9417. }
  9418. if (a) {
  9419. //$(elem1).empty(); // ???
  9420. $(elem1).append(a);
  9421. setTimeout(function () {
  9422. var isSelected1; // undefined
  9423. $("option", elem1).each(function (iOpt) {
  9424. //if(i===0) { this.selected = false; }
  9425. // fix IE8/IE7 problem with selecting of the first item on multiple=true
  9426. if (iOpt === 0 && elem1.multiple) { this.selected = false; }
  9427. if ($.inArray($.trim($(this).val()), ovm1) > -1) {
  9428. // this.setAttribute("selected", "selected");
  9429. this.selected = true;
  9430. isSelected1 = true;
  9431. }
  9432. });
  9433. if (!isSelected1) {
  9434. $("option", elem1).each(function () {
  9435. if ($.inArray($.trim($(this).text()), ovm1) > -1) {
  9436. // this.setAttribute("selected", "selected");
  9437. this.selected = true;
  9438. }
  9439. });
  9440. }
  9441. //$(elem1).change();
  9442. jgrid.fullBoolFeedback.call($t, options1.selectFilled, "jqGridSelectFilled", {
  9443. elem: elem1,
  9444. options: options1,
  9445. cm: cm1,
  9446. rowid: rowid1,
  9447. mode: mode1,
  9448. cmName: cm1 != null ? cm1.name : options1.name,
  9449. iCol: iCol1
  9450. });
  9451. }, 0);
  9452. }
  9453. }
  9454. }, ajaxso || {}));
  9455. } else if (options.value) {
  9456. jgrid.fillSelectOptions(
  9457. elem,
  9458. options.value,
  9459. options.separator === undefined ? ":" : options.separator,
  9460. options.delimiter === undefined ? ";" : options.delimiter,
  9461. msl,
  9462. vl
  9463. );
  9464. setAttributes(elem, options, ["value"]);
  9465. jgrid.fullBoolFeedback.call($t, options.selectFilled, "jqGridSelectFilled", {
  9466. elem: elem,
  9467. options: options,
  9468. cm: options.cm,
  9469. rowid: rowid,
  9470. mode: options.mode,
  9471. cmName: options.cm != null ? options.cm.name : options.name,
  9472. iCol: options.iCol
  9473. });
  9474. }
  9475. break;
  9476. case "text":
  9477. case "password":
  9478. case "button":
  9479. var role;
  9480. if (eltype === "button") {
  9481. role = "button";
  9482. } else {
  9483. role = "textbox";
  9484. }
  9485. elem = document.createElement("input");
  9486. elem.type = eltype;
  9487. setAttributes(elem, options);
  9488. elem.value = vl;
  9489. if (eltype !== "button") {
  9490. if (autowidth) {
  9491. if (!options.size) { $(elem).css({ width: "100%", "box-sizing": "border-box" }); }
  9492. } else if (!options.size) {
  9493. options.size = 20;
  9494. }
  9495. }
  9496. $(elem).attr("role", role);
  9497. break;
  9498. case "image":
  9499. case "file":
  9500. elem = document.createElement("input");
  9501. elem.type = eltype;
  9502. setAttributes(elem, options);
  9503. break;
  9504. case "custom":
  9505. elem = document.createElement("span");
  9506. try {
  9507. if ($.isFunction(options.custom_element)) {
  9508. var celm = options.custom_element.call($t, vl, options);
  9509. if (celm instanceof jQuery || jgrid.isHTMLElement(celm) || typeof celm === "string") {
  9510. celm = $(celm).addClass("customelement").attr({ id: options.id, name: options.name });
  9511. $(elem).empty().append(celm);
  9512. } else {
  9513. throw "editoptions.custom_element returns value of a wrong type";
  9514. }
  9515. } else {
  9516. throw "editoptions.custom_element is not a function";
  9517. }
  9518. } catch (e) {
  9519. if (e === "e1") {
  9520. infoDialog.call($t, errcap, "function 'custom_element' " + editMsg.nodefined, bClose);
  9521. }
  9522. if (e === "e2") {
  9523. infoDialog.call($t, errcap, "function 'custom_element' " + editMsg.novalue, bClose);
  9524. } else {
  9525. infoDialog.call($t, errcap, typeof e === "string" ? e : e.message, bClose);
  9526. }
  9527. }
  9528. break;
  9529. }
  9530. return elem;
  9531. },
  9532. // Date Validation Javascript
  9533. checkDate: function (format, date) {
  9534. var daysInFebruary = function (year) {
  9535. // February has 29 days in any year evenly divisible by four,
  9536. // EXCEPT for centurial years which are not also divisible by 400.
  9537. return (((year % 4 === 0) && (year % 100 !== 0 || (year % 400 === 0))) ? 29 : 28);
  9538. },
  9539. tsp = {},
  9540. sep;
  9541. format = format.toLowerCase();
  9542. //we search for /,-,. for the date separator
  9543. if (format.indexOf("/") !== -1) {
  9544. sep = "/";
  9545. } else if (format.indexOf("-") !== -1) {
  9546. sep = "-";
  9547. } else if (format.indexOf(".") !== -1) {
  9548. sep = ".";
  9549. } else {
  9550. sep = "/";
  9551. }
  9552. format = format.split(sep);
  9553. date = date.split(sep);
  9554. if (date.length !== 3) { return false; }
  9555. var j = -1, yln, dln = -1, mln = -1, i, dv;
  9556. for (i = 0; i < format.length; i++) {
  9557. dv = isNaN(date[i]) ? 0 : parseInt(date[i], 10);
  9558. tsp[format[i]] = dv;
  9559. yln = format[i];
  9560. if (yln.indexOf("y") !== -1) { j = i; }
  9561. if (yln.indexOf("m") !== -1) { mln = i; }
  9562. if (yln.indexOf("d") !== -1) { dln = i; }
  9563. }
  9564. if (format[j] === "y" || format[j] === "yyyy") {
  9565. yln = 4;
  9566. } else if (format[j] === "yy") {
  9567. yln = 2;
  9568. } else {
  9569. yln = -1;
  9570. }
  9571. var strDate, daysInMonth = [0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];
  9572. if (j === -1) {
  9573. return false;
  9574. }
  9575. strDate = tsp[format[j]].toString();
  9576. if (yln === 2 && strDate.length === 1) { yln = 1; }
  9577. if (strDate.length !== yln || (tsp[format[j]] === 0 && date[j] !== "00")) {
  9578. return false;
  9579. }
  9580. if (mln === -1) {
  9581. return false;
  9582. }
  9583. strDate = tsp[format[mln]].toString();
  9584. if (strDate.length < 1 || tsp[format[mln]] < 1 || tsp[format[mln]] > 12) {
  9585. return false;
  9586. }
  9587. if (dln === -1) {
  9588. return false;
  9589. }
  9590. strDate = tsp[format[dln]].toString();
  9591. if (strDate.length < 1 || tsp[format[dln]] < 1 || tsp[format[dln]] > 31 || (tsp[format[mln]] === 2 && tsp[format[dln]] > daysInFebruary(tsp[format[j]])) || tsp[format[dln]] > daysInMonth[tsp[format[mln]]]) {
  9592. return false;
  9593. }
  9594. return true;
  9595. },
  9596. isEmpty: function (val) {
  9597. if (val.match(/^\s+$/) || val === "") {
  9598. return true;
  9599. }
  9600. return false;
  9601. },
  9602. checkTime: function (time) {
  9603. // checks only hh:ss (and optional am/pm)
  9604. var re = /^(\d{1,2}):(\d{2})([apAP][Mm])?$/, regs;
  9605. if (!jgrid.isEmpty(time)) {
  9606. regs = time.match(re);
  9607. if (regs) {
  9608. if (regs[3]) {
  9609. if (regs[1] < 1 || regs[1] > 12) { return false; }
  9610. } else {
  9611. if (regs[1] > 23) { return false; }
  9612. }
  9613. if (regs[2] > 59) {
  9614. return false;
  9615. }
  9616. } else {
  9617. return false;
  9618. }
  9619. }
  9620. return true;
  9621. },
  9622. checkValues: function (val, iCol, customobject, nam, options) {
  9623. var edtrul, nm, dft, g = this, p = g.p, colModel = p.colModel, cm, isEmpty = jgrid.isEmpty,
  9624. editMsg = getGridRes.call($(g), "edit.msg"), ret,
  9625. getPropertyValue = function (propertyName) {
  9626. var propValue = edtrul[propertyName];
  9627. return $.isFunction(propValue) ? propValue.call(g, options) : propValue;
  9628. },
  9629. dateMasks = getGridRes.call($(g), "formatter.date.masks");
  9630. if (customobject === undefined) {
  9631. if (typeof iCol === "string") {
  9632. iCol = p.iColByName[iCol];
  9633. }
  9634. if (iCol === undefined || iCol < 0) {
  9635. return [true, "", ""];
  9636. }
  9637. cm = colModel[iCol];
  9638. edtrul = cm.editrules;
  9639. if (cm.formoptions != null) { nm = cm.formoptions.label; }
  9640. } else {
  9641. edtrul = customobject;
  9642. nm = nam === undefined ? "_" : nam;
  9643. cm = colModel[iCol];
  9644. }
  9645. if (edtrul) {
  9646. if (!nm) { nm = p.colNames != null ? p.colNames[iCol] : cm.label; }
  9647. if (getPropertyValue("required") === true) {
  9648. if (isEmpty(val)) { return [false, nm + ": " + editMsg.required, ""]; }
  9649. }
  9650. // force required
  9651. var rqfield = getPropertyValue("required") === false ? false : true;
  9652. if (getPropertyValue("number") === true) {
  9653. if (!(rqfield === false && isEmpty(val))) {
  9654. if (isNaN(val)) { return [false, nm + ": " + editMsg.number, ""]; }
  9655. }
  9656. }
  9657. if (edtrul.minValue !== undefined && !isNaN(edtrul.minValue)) {
  9658. if (parseFloat(val) < parseFloat(edtrul.minValue)) { return [false, nm + ": " + editMsg.minValue + " " + edtrul.minValue, ""]; }
  9659. }
  9660. if (edtrul.maxValue !== undefined && !isNaN(edtrul.maxValue)) {
  9661. if (parseFloat(val) > parseFloat(edtrul.maxValue)) { return [false, nm + ": " + editMsg.maxValue + " " + edtrul.maxValue, ""]; }
  9662. }
  9663. var filter;
  9664. if (getPropertyValue("email") === true) {
  9665. if (!(rqfield === false && isEmpty(val))) {
  9666. // taken from $ Validate plugin
  9667. filter = /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i;
  9668. if (!filter.test(val)) { return [false, nm + ": " + editMsg.email, ""]; }
  9669. }
  9670. }
  9671. if (getPropertyValue("integer") === true) {
  9672. if (!(rqfield === false && isEmpty(val))) {
  9673. if (isNaN(val)) { return [false, nm + ": " + editMsg.integer, ""]; }
  9674. if ((val % 1 !== 0) || (val.indexOf(".") !== -1)) { return [false, nm + ": " + editMsg.integer, ""]; }
  9675. }
  9676. }
  9677. if (getPropertyValue("date") === true) {
  9678. if (!(rqfield === false && isEmpty(val))) {
  9679. if (cm.formatoptions && cm.formatoptions.newformat) {
  9680. dft = cm.formatoptions.newformat;
  9681. if (dateMasks.hasOwnProperty(dft)) {
  9682. dft = dateMasks[dft];
  9683. }
  9684. } else {
  9685. dft = colModel[iCol].datefmt || "Y-m-d";
  9686. }
  9687. if (!jgrid.checkDate(dft, val)) { return [false, nm + ": " + editMsg.date + " - " + dft, ""]; }
  9688. }
  9689. }
  9690. if (getPropertyValue("time") === true) {
  9691. if (!(rqfield === false && isEmpty(val))) {
  9692. if (!jgrid.checkTime(val)) { return [false, nm + ": " + editMsg.date + " - hh:mm (am/pm)", ""]; }
  9693. }
  9694. }
  9695. if (getPropertyValue("url") === true) {
  9696. if (!(rqfield === false && isEmpty(val))) {
  9697. filter = /^(((https?)|(ftp)):\/\/([\-\w]+\.)+\w{2,3}(\/[%\-\w]+(\.\w{2,})?)*(([\w\-\.\?\\\/+@&#;`~=%!]*)(\.\w{2,})?)*\/?)/i;
  9698. if (!filter.test(val)) { return [false, nm + ": " + editMsg.url, ""]; }
  9699. }
  9700. }
  9701. if (edtrul.custom === true) {
  9702. if (!(rqfield === false && isEmpty(val))) {
  9703. if ($.isFunction(edtrul.custom_func)) {
  9704. ret = edtrul.custom_func.call(g, val, nm, iCol);
  9705. return $.isArray(ret) ? ret : [false, editMsg.customarray, ""];
  9706. }
  9707. return [false, editMsg.customfcheck, ""];
  9708. }
  9709. } else if ($.isFunction(edtrul.custom)) {
  9710. if (!(rqfield === false && isEmpty(val))) {
  9711. ret = edtrul.custom.call(g, options);
  9712. return $.isArray(ret) ? ret : [false, editMsg.customarray, ""];
  9713. }
  9714. }
  9715. }
  9716. return [true, "", ""];
  9717. }
  9718. });
  9719. // end module grid.common
  9720. /**
  9721. * jqGrid extension for custom methods
  9722. * Tony Tomov tony@trirand.com, http://trirand.com/blog/
  9723. *
  9724. * Wildraid wildraid@mail.ru
  9725. * Oleg Kiriljuk oleg.kiriljuk@ok-soft-gmbh.com
  9726. * Dual licensed under the MIT and GPL licenses:
  9727. * http://www.opensource.org/licenses/mit-license.php
  9728. * http://www.gnu.org/licenses/gpl-2.0.html
  9729. **/
  9730. // begin module grid.custom
  9731. jgrid.extend({
  9732. getColProp: function (colname) {
  9733. var ret = {}, t = this[0], iCol;
  9734. if (t != null && t.grid) {
  9735. iCol = t.p.iColByName[colname];
  9736. if (iCol !== undefined) {
  9737. return t.p.colModel[iCol];
  9738. }
  9739. }
  9740. return ret;
  9741. },
  9742. setColProp: function (colname, obj) {
  9743. //do not set width will not work
  9744. return this.each(function () {
  9745. var self = this, p = self.p, iCol;
  9746. if (self.grid && p != null && obj) {
  9747. iCol = p.iColByName[colname];
  9748. if (iCol !== undefined) {
  9749. $.extend(true, p.colModel[iCol], obj);
  9750. }
  9751. }
  9752. });
  9753. },
  9754. sortGrid: function (colname, reload, sor) {
  9755. return this.each(function () {
  9756. var self = this, grid = self.grid, p = self.p, colModel = p.colModel, l = colModel.length, cm, i, sobj = false, sort;
  9757. if (!grid) { return; }
  9758. if (!colname) { colname = p.sortname; }
  9759. if (typeof reload !== "boolean") { reload = false; }
  9760. for (i = 0; i < l; i++) {
  9761. cm = colModel[i];
  9762. if (cm.index === colname || cm.name === colname) {
  9763. if (p.frozenColumns === true && cm.frozen === true) {
  9764. sobj = grid.fhDiv.find("#" + jqID(p.id + "_" + colname));
  9765. }
  9766. if (!sobj || sobj.length === 0) {
  9767. sobj = grid.headers[i].el;
  9768. }
  9769. sort = cm.sortable;
  9770. if (typeof sort !== "boolean" || sort) {
  9771. self.sortData(cm.index || cm.name, i, reload, sor, sobj);
  9772. }
  9773. break;
  9774. }
  9775. }
  9776. });
  9777. },
  9778. clearBeforeUnload: function () {
  9779. return this.each(function () {
  9780. var self = this, p = self.p, grid = self.grid, propOrMethod, clearArray = jgrid.clearArray,
  9781. hasOwnProperty = Object.prototype.hasOwnProperty;
  9782. if ($.isFunction(grid.emptyRows)) {
  9783. grid.emptyRows.call(self, true, true); // this work quick enough and reduce the size of memory leaks if we have someone
  9784. }
  9785. $(document).off("mousemove.jqGrid mouseup.jqGrid" + p.id);
  9786. $(self).off();
  9787. /*grid.dragEnd = null;
  9788. grid.dragMove = null;
  9789. grid.dragStart = null;
  9790. grid.emptyRows = null;
  9791. grid.populate = null;
  9792. grid.populateVisible = null;
  9793. grid.scrollGrid = null;
  9794. grid.selectionPreserver = null;
  9795. grid.bDiv = null;
  9796. grid.fbRows = null;
  9797. grid.cDiv = null;
  9798. grid.hDiv = null;
  9799. grid.cols = null;*/
  9800. var i, l = grid.headers.length;
  9801. for (i = 0; i < l; i++) {
  9802. grid.headers[i].el = null;
  9803. }
  9804. for (propOrMethod in grid) {
  9805. if (grid.hasOwnProperty(propOrMethod)) {
  9806. grid.propOrMethod = null;
  9807. }
  9808. }
  9809. /*self.formatCol = null;
  9810. self.sortData = null;
  9811. self.updatepager = null;
  9812. self.refreshIndex = null;
  9813. self.setHeadCheckBox = null;
  9814. self.constructTr = null;
  9815. self.formatter = null;
  9816. self.addXmlData = null;
  9817. self.addJSONData = null;
  9818. self.grid = null;*/
  9819. var propOrMethods = ["formatCol", "sortData", "updatepager", "refreshIndex", "setHeadCheckBox", "constructTr", "clearToolbar", "fixScrollOffsetAndhBoxPadding", "rebuildRowIndexes", "modalAlert", "toggleToolbar", "triggerToolbar", "formatter", "addXmlData", "addJSONData", "ftoolbar", "_inlinenav", "nav", "grid", "p"];
  9820. l = propOrMethods.length;
  9821. for (i = 0; i < l; i++) {
  9822. if (hasOwnProperty.call(self, propOrMethods[i])) {
  9823. self[propOrMethods[i]] = null;
  9824. }
  9825. }
  9826. self._index = {};
  9827. clearArray(p.data);
  9828. clearArray(p.lastSelectedData);
  9829. clearArray(p.selarrrow);
  9830. clearArray(p.savedRow);
  9831. p.editingInfo = {};
  9832. });
  9833. },
  9834. GridDestroy: function () {
  9835. return this.each(function () {
  9836. var self = this, p = self.p;
  9837. if (self.grid && p != null) {
  9838. if (p.pager) { // if not part of grid
  9839. $(p.pager).remove();
  9840. }
  9841. try {
  9842. $("#alertmod_" + jqID(p.id)).remove();
  9843. $(self).jqGrid("clearBeforeUnload");
  9844. $(p.gBox).remove();
  9845. } catch (ignore) { }
  9846. }
  9847. });
  9848. },
  9849. GridUnload: function () {
  9850. return this.each(function () {
  9851. var self = this, $self = $(self), p = self.p, $j = $.fn.jqGrid;
  9852. if (!self.grid) { return; }
  9853. $self.removeClass($j.getGuiStyles.call($self, "grid", "ui-jqgrid-btable"));
  9854. // The multiple removeAttr can be replace to one after dropping of support of old jQuery
  9855. if (p.pager) {
  9856. if (p.pager.substr(1, $.jgrid.uidPref.length) === $.jgrid.uidPref) {
  9857. $(p.pager).remove();
  9858. } else {
  9859. $(p.pager).empty()
  9860. .removeClass($j.getGuiStyles.call($self, "pager.pager", "ui-jqgrid-pager " +
  9861. $j.getGuiStyles.call($self, "bottom")))
  9862. .removeAttr("style")
  9863. .removeAttr("dir");
  9864. }
  9865. }
  9866. $self.jqGrid("clearBeforeUnload");
  9867. $self.removeAttr("style")
  9868. .removeAttr("tabindex")
  9869. .removeAttr("role")
  9870. .removeAttr("aria-labelledby")
  9871. .removeAttr("style");
  9872. $self.empty(); // remove the first line
  9873. $self.insertBefore(p.gBox).show();
  9874. $(p.pager).insertBefore(p.gBox).show();
  9875. $(p.gBox).remove();
  9876. });
  9877. },
  9878. setGridState: function (state) {
  9879. return this.each(function () {
  9880. var $t = this, p = $t.p, grid = $t.grid, cDiv = grid.cDiv, $uDiv = $(grid.uDiv), $ubDiv = $(grid.ubDiv);
  9881. if (!grid || p == null) { return; }
  9882. var getMinimizeIcon = function (path) {
  9883. return base.getIconRes.call($t, "gridMinimize." + path);
  9884. },
  9885. visibleGridIcon = getMinimizeIcon("visible"),
  9886. hiddenGridIcon = getMinimizeIcon("hidden");
  9887. if (state === "hidden") {
  9888. $(".ui-jqgrid-bdiv, .ui-jqgrid-hdiv", p.gView).slideUp("fast");
  9889. if (p.pager) { $(p.pager).slideUp("fast"); }
  9890. if (p.toppager) { $(p.toppager).slideUp("fast"); }
  9891. if (p.toolbar[0] === true) {
  9892. if (p.toolbar[1] === "both") {
  9893. $ubDiv.slideUp("fast");
  9894. }
  9895. $uDiv.slideUp("fast");
  9896. }
  9897. if (p.footerrow) { $(".ui-jqgrid-sdiv", p.gBox).slideUp("fast"); }
  9898. $(".ui-jqgrid-titlebar-close span", cDiv).removeClass(visibleGridIcon).addClass(hiddenGridIcon);
  9899. p.gridstate = "hidden";
  9900. } else if (state === "visible") {
  9901. $(".ui-jqgrid-hdiv, .ui-jqgrid-bdiv", p.gView).slideDown("fast");
  9902. if (p.pager) { $(p.pager).slideDown("fast"); }
  9903. if (p.toppager) { $(p.toppager).slideDown("fast"); }
  9904. if (p.toolbar[0] === true) {
  9905. if (p.toolbar[1] === "both") {
  9906. $ubDiv.slideDown("fast");
  9907. }
  9908. $uDiv.slideDown("fast");
  9909. }
  9910. if (p.footerrow) { $(".ui-jqgrid-sdiv", p.gBox).slideDown("fast"); }
  9911. $(".ui-jqgrid-titlebar-close span", cDiv).removeClass(hiddenGridIcon).addClass(visibleGridIcon);
  9912. p.gridstate = "visible";
  9913. }
  9914. });
  9915. },
  9916. filterToolbar: function (oMuligrid) {
  9917. // if one uses jQuery wrapper with multiple grids, then oMultiple specify the object with common options
  9918. return this.each(function () {
  9919. var $t = this, grid = $t.grid, $self = $($t), p = $t.p, infoDialog = jgrid.info_dialog, htmlEncode = jgrid.htmlEncode;
  9920. if (this.ftoolbar) { return; }
  9921. // make new copy of the options and use it for ONE specific grid.
  9922. // p.searching can contains grid specific options
  9923. // we will don't modify the input options oMuligrid
  9924. var o = $.extend(true, {
  9925. autosearch: true,
  9926. autosearchDelay: 500,
  9927. searchOnEnter: true,
  9928. beforeSearch: null,
  9929. afterSearch: null,
  9930. beforeClear: null,
  9931. afterClear: null,
  9932. searchurl: "",
  9933. sField: "searchField",
  9934. sValue: "searchString",
  9935. sOper: "searchOper",
  9936. sFilter: p.prmNames.filters,
  9937. stringResult: false,
  9938. groupOp: "AND",
  9939. defaultSearch: "bw",
  9940. idMode: "new", // support "old", "compatibility", "new"
  9941. searchOperators: false,
  9942. resetIcon: "&times;",
  9943. applyLabelClasses: true,
  9944. loadFilterDefaults: true, // this options activates loading of default filters from grid's postData for Multipe Search only.
  9945. operands: { "eq": "==", "ne": "!", "lt": "<", "le": "<=", "gt": ">", "ge": ">=", "bw": "^", "bn": "!^", "in": "=", "ni": "!=", "ew": "|", "en": "!@", "cn": "~", "nc": "!~", "nu": "#", "nn": "!#" }
  9946. }, jgrid.search, p.searching || {}, oMuligrid || {}),
  9947. colModel = p.colModel,
  9948. getRes = function (path) {
  9949. return getGridRes.call($self, path);
  9950. },
  9951. errcap = getRes("errors.errcap"),
  9952. bClose = getRes("edit.bClose"),
  9953. editMsg = getRes("edit.msg"),
  9954. hoverClasses = getGuiStyles.call($t, "states.hover"),
  9955. highlightClass = getGuiStyles.call($t, "states.select"),
  9956. dataFieldClass = getGuiStyles.call($t, "filterToolbar.dataField"),
  9957. currentFilters = {},
  9958. getId = function (cmName) {
  9959. var prefix = "gs_";
  9960. switch (o.idMode) {
  9961. case "compatibility":
  9962. prefix += p.idPrefix;
  9963. break;
  9964. case "new":
  9965. prefix += p.id + "_";
  9966. break;
  9967. default: // "old"
  9968. break;
  9969. }
  9970. return prefix + cmName;
  9971. },
  9972. getIdSel = function (cmName) {
  9973. return "#" + jqID(getId(cmName));
  9974. },
  9975. getOnOffValue = function (soptions) {
  9976. var checkboxValue = (soptions.value || "").split(":");
  9977. return {
  9978. on: checkboxValue[0] || "on",
  9979. off: checkboxValue[1] || "off"
  9980. };
  9981. },
  9982. parseFilter = function (fillAll) {
  9983. var i, j, filters = p.postData[o.sFilter], filter = {}, rules, rule,
  9984. iColByName = p.iColByName, cm, soptions;
  9985. if (fillAll) {
  9986. for (j = 0; j < colModel.length; j++) {
  9987. cm = colModel[j];
  9988. if (cm.search !== false) {
  9989. soptions = cm.searchoptions || {};
  9990. filter[cm.name] = {
  9991. op: soptions.sopt ?
  9992. soptions.sopt[0] :
  9993. (cm.stype === "select" || cm.stype === "checkbox") ? "eq" : o.defaultSearch,
  9994. data: soptions.defaultValue !== undefined ? soptions.defaultValue : ""
  9995. };
  9996. }
  9997. }
  9998. }
  9999. // TODO: test for !o.stringResult && !o.searchOperators && p.datatype !== "local"
  10000. // and use p.postData[cm.index || cm.name] instead of filter[cm.name]
  10001. if (!filters || !p.search) { return filter; }
  10002. if (typeof filters === "string") {
  10003. try {
  10004. filters = $.parseJSON(filters);
  10005. } catch (ignore) {
  10006. filters = {};
  10007. }
  10008. } else {
  10009. filters = filters || {};
  10010. }
  10011. rules = filters.rules || {};
  10012. if (filters == null ||
  10013. (filters.groupOp != null && o.groupOp != null && filters.groupOp.toUpperCase() !== o.groupOp.toUpperCase()) ||
  10014. rules == null || rules.length === 0 ||
  10015. (filters.groups != null && filters.groups.length > 0)) {
  10016. return filter;
  10017. }
  10018. for (j = 0; j < rules.length; j++) {
  10019. rule = rules[j];
  10020. // find all columns in colModel, where
  10021. // colModel[i].index || colModel[i].name === rule.field
  10022. cm = colModel[iColByName[rule.field]];
  10023. for (i = 0; i < colModel.length; i++) {
  10024. cm = colModel[i];
  10025. if ((cm.index || cm.name) !== rule.field || cm.search === false) {
  10026. continue;
  10027. }
  10028. soptions = cm.searchoptions || {};
  10029. if (soptions.sopt) {
  10030. if ($.inArray(rule.op, soptions.sopt) < 0) {
  10031. continue;
  10032. }
  10033. } else if (cm.stype === "select" || cm.stype === "checkbox") {
  10034. if (rule.op !== "eq") {
  10035. continue;
  10036. }
  10037. } else if (rule.op !== o.defaultSearch) {
  10038. continue;
  10039. }
  10040. filter[cm.name] = { op: rule.op, data: rule.data };
  10041. }
  10042. }
  10043. return filter;
  10044. },
  10045. setThreeStateCheckbox = function ($checkbox, state) {
  10046. switch (state) {
  10047. case 1: // make checked
  10048. $checkbox.data("state", 1)
  10049. .prop({
  10050. checked: true,
  10051. indeterminate: false
  10052. });
  10053. break;
  10054. case 0: // make unchecked
  10055. $checkbox.data("state", 0)
  10056. .prop({
  10057. checked: false,
  10058. indeterminate: false
  10059. });
  10060. break;
  10061. default: // make indeterminate
  10062. $checkbox.data("state", -1)
  10063. .prop({
  10064. checked: false,
  10065. indeterminate: true
  10066. });
  10067. break;
  10068. }
  10069. },
  10070. triggerToolbar = function () {
  10071. var sdata = {}, j = 0, sopt = {};
  10072. $.each(colModel, function () {
  10073. var cm = this, nm = cm.index || cm.name, v, so, searchoptions = cm.searchoptions || {},
  10074. $elem = $(getIdSel(cm.name), (cm.frozen === true && p.frozenColumns === true) ? grid.fhDiv : grid.hDiv),
  10075. getFormaterOption = function (optionName, formatter) {
  10076. var formatoptions = cm.formatoptions || {};
  10077. return formatoptions[optionName] !== undefined ?
  10078. formatoptions[optionName] :
  10079. getRes("formatter." + (formatter || cm.formatter) + "." + optionName);
  10080. },
  10081. cutThousandsSeparator = function (val) {
  10082. var separator = getFormaterOption("thousandsSeparator")
  10083. .replace(/([\.\*\_\'\(\)\{\}\+\?\\])/g, "\\$1");
  10084. return val.replace(new RegExp(separator, "g"), "");
  10085. };
  10086. if (o.searchOperators) {
  10087. so = $elem.parent().prev().children("a").data("soper") || o.defaultSearch;
  10088. } else {
  10089. so = searchoptions.sopt ? searchoptions.sopt[0] : (cm.stype === "select" || cm.stype === "checkbox") ? "eq" : o.defaultSearch;
  10090. }
  10091. /* the format of element of the searching toolbar if ANOTHER
  10092. * as the format of cells in the grid. So one can't use
  10093. * value = $.unformat.call($t, $elem, { colModel: cm }, iCol)
  10094. * to get the value. Even the access to the value should be
  10095. * $elem.val() instead of $elem.text() used in the common case of
  10096. * formatter. So we have to make manual conversion of searching filed
  10097. * used for integer/number/currency. The code will be duplicate */
  10098. if (cm.stype === "custom" && $.isFunction(searchoptions.custom_value) && $elem.length > 0 && $elem[0].nodeName.toUpperCase() === "SPAN") {
  10099. v = searchoptions.custom_value.call($t, $elem.children(".customelement").first(), "get");
  10100. } else if (cm.stype === "select") {
  10101. if ($elem.prop("multiple")) {
  10102. v = $elem.val();
  10103. if (v == null || v.length === 0) {
  10104. v = "";
  10105. } else {
  10106. v = v.join(p.inFilterSeparator || ",");
  10107. }
  10108. } else {
  10109. v = $elem.val();
  10110. }
  10111. } else if (cm.stype === "checkbox") {
  10112. var onOffValue = getOnOffValue(searchoptions);
  10113. switch ($elem.data("state")) {
  10114. case -1: // has indeterminate state
  10115. v = "";
  10116. break;
  10117. case 0: // is unchecked
  10118. // make indeterminate
  10119. v = onOffValue.off;
  10120. break;
  10121. default: // is checked
  10122. // make unchecked
  10123. v = onOffValue.on;
  10124. break;
  10125. }
  10126. } else {
  10127. v = $.trim($elem.val());
  10128. switch (cm.formatter) {
  10129. case "integer":
  10130. v = cutThousandsSeparator(v)
  10131. .replace(getFormaterOption("decimalSeparator", "number"), ".");
  10132. if (v !== "") {
  10133. // normalize the strings like "010.01" to "10"
  10134. v = String(parseInt(v, 10));
  10135. }
  10136. break;
  10137. case "number":
  10138. v = cutThousandsSeparator(v)
  10139. .replace(getFormaterOption("decimalSeparator"), ".");
  10140. if (v !== "" && String(v).charAt(0) === "0") {
  10141. // normalize the strings like "010.00" to "10"
  10142. // and "010.12" to "10.12"
  10143. v = String(parseFloat(v));
  10144. }
  10145. break;
  10146. case "currency":
  10147. var prefix = getFormaterOption("prefix"),
  10148. suffix = getFormaterOption("suffix");
  10149. if (prefix && prefix.length && v.substr(0, prefix.length) === prefix) {
  10150. v = v.substr(prefix.length);
  10151. }
  10152. if (suffix && suffix.length && v.length > suffix.length && v.substr(v.length - suffix.length, suffix.length) === suffix) {
  10153. v = v.substr(0, v.length - suffix.length);
  10154. }
  10155. v = cutThousandsSeparator(v)
  10156. .replace(getFormaterOption("decimalSeparator"), ".");
  10157. if (v !== "") {
  10158. // normalize the strings like "010.00" to "10"
  10159. // and "010.12" to "10.12"
  10160. v = String(parseFloat(v));
  10161. }
  10162. break;
  10163. default:
  10164. // TODO: call unformatter if it's defined.
  10165. break;
  10166. }
  10167. }
  10168. if (v || so === "nu" || so === "nn" || $.inArray(so, p.customUnaryOperations) >= 0) {
  10169. sdata[nm] = v;
  10170. sopt[nm] = so;
  10171. j++;
  10172. } else {
  10173. if (sdata.hasOwnProperty(nm)) {
  10174. delete sdata[nm];
  10175. }
  10176. if (!(o.stringResult || o.searchOperators || p.datatype === "local")) {
  10177. try {
  10178. if (p.postData != null && p.postData.hasOwnProperty(nm)) {
  10179. delete p.postData[nm];
  10180. }
  10181. } catch (ignore) { }
  10182. }
  10183. }
  10184. });
  10185. var sd = j > 0 ? true : false;
  10186. if (o.stringResult || o.searchOperators || p.datatype === "local") {
  10187. var ruleGroup = '{"groupOp":"' + o.groupOp + '","rules":[';
  10188. var gi = 0;
  10189. $.each(sdata, function (cmName, n) {
  10190. //var iCol = p.iColByName[cmName], cm = p.colModel[iCol],
  10191. // value = $.unformat.call($t, $("<span></span>").text(n), { colModel: cm }, iCol);
  10192. if (gi > 0) { ruleGroup += ","; }
  10193. ruleGroup += '{"field":"' + cmName + '",';
  10194. ruleGroup += '"op":"' + sopt[cmName] + '",';
  10195. n += "";
  10196. ruleGroup += '"data":"' + n.replace(/\\/g, "\\\\").replace(/\"/g, '\\"') + '"}';
  10197. gi++;
  10198. });
  10199. ruleGroup += "]}";
  10200. p.postData[o.sFilter] = ruleGroup;
  10201. $.each([o.sField, o.sValue, o.sOper], function (i, n) {
  10202. if (p.postData.hasOwnProperty(n)) { delete p.postData[n]; }
  10203. });
  10204. } else {
  10205. $.extend(p.postData, sdata);
  10206. }
  10207. var saveurl;
  10208. if (p.searchurl) {
  10209. saveurl = p.url;
  10210. $self.jqGrid("setGridParam", { url: p.searchurl });
  10211. }
  10212. var bsr = $self.triggerHandler("jqGridToolbarBeforeSearch") === "stop" ? true : false;
  10213. if (!bsr && $.isFunction(o.beforeSearch)) { bsr = o.beforeSearch.call($t); }
  10214. if (!bsr) {
  10215. $self.jqGrid("setGridParam", { search: sd })
  10216. .trigger("reloadGrid", [$.extend({ page: 1 }, o.reloadGridSearchOptions || {})]);
  10217. }
  10218. if (saveurl) { $self.jqGrid("setGridParam", { url: saveurl }); }
  10219. $self.triggerHandler("jqGridToolbarAfterSearch");
  10220. if ($.isFunction(o.afterSearch)) { o.afterSearch.call($t); }
  10221. },
  10222. clearToolbar = function (trigger) {
  10223. var sdata = {}, j = 0, nm;
  10224. trigger = (typeof trigger !== "boolean") ? true : trigger;
  10225. $.each(colModel, function () {
  10226. var v, cm = this, $elem = $(getIdSel(cm.name), (cm.frozen === true && p.frozenColumns === true) ? grid.fhDiv : grid.hDiv),
  10227. isSindleSelect, searchoptions = cm.searchoptions || {};
  10228. if (searchoptions.defaultValue !== undefined) { v = searchoptions.defaultValue; }
  10229. nm = cm.index || cm.name;
  10230. switch (cm.stype) {
  10231. case "checkbox":
  10232. // set indeterminate state
  10233. setThreeStateCheckbox($elem, -1);
  10234. break;
  10235. case "select":
  10236. isSindleSelect = $elem.length > 0 ? !$elem[0].multiple : true;
  10237. $elem.find("option").each(function (i) {
  10238. this.selected = i === 0 && isSindleSelect;
  10239. if ($(this).val() === v) {
  10240. this.selected = true;
  10241. return false;
  10242. }
  10243. });
  10244. if (v !== undefined) {
  10245. // post the key and not the text
  10246. sdata[nm] = v;
  10247. j++;
  10248. } else {
  10249. try {
  10250. delete p.postData[nm];
  10251. } catch (ignore) { }
  10252. }
  10253. break;
  10254. case "text":
  10255. $elem.val(v || "");
  10256. if (v !== undefined) {
  10257. sdata[nm] = v;
  10258. j++;
  10259. } else {
  10260. try {
  10261. delete p.postData[nm];
  10262. } catch (ignore) { }
  10263. }
  10264. break;
  10265. case "custom":
  10266. if ($.isFunction(searchoptions.custom_value) && $elem.length > 0 && $elem[0].nodeName.toUpperCase() === "SPAN") {
  10267. if (v === undefined) {
  10268. v = "";
  10269. }
  10270. searchoptions.custom_value.call($t, $elem.children(".customelement").first(), "set", v);
  10271. }
  10272. break;
  10273. }
  10274. });
  10275. var sd = j > 0 ? true : false;
  10276. p.resetsearch = true;
  10277. if (o.stringResult || o.searchOperators || p.datatype === "local") {
  10278. var ruleGroup = '{"groupOp":"' + o.groupOp + '","rules":[';
  10279. var gi = 0;
  10280. $.each(sdata, function (i, n) {
  10281. if (gi > 0) { ruleGroup += ","; }
  10282. ruleGroup += '{"field":"' + i + '",';
  10283. ruleGroup += '"op":"' + "eq" + '",';
  10284. n += "";
  10285. ruleGroup += '"data":"' + n.replace(/\\/g, "\\\\").replace(/\"/g, '\\"') + '"}';
  10286. gi++;
  10287. });
  10288. ruleGroup += "]}";
  10289. p.postData[o.sFilter] = ruleGroup;
  10290. $.each([o.sField, o.sValue, o.sOper], function (i, n) {
  10291. if (p.postData.hasOwnProperty(n)) { delete p.postData[n]; }
  10292. });
  10293. } else {
  10294. $.extend(p.postData, sdata);
  10295. }
  10296. var saveurl;
  10297. if (p.searchurl) {
  10298. saveurl = p.url;
  10299. $self.jqGrid("setGridParam", { url: p.searchurl });
  10300. }
  10301. var bcv = $self.triggerHandler("jqGridToolbarBeforeClear") === "stop" ? true : false;
  10302. if (!bcv && $.isFunction(o.beforeClear)) { bcv = o.beforeClear.call($t); }
  10303. if (!bcv) {
  10304. if (trigger) {
  10305. $self.jqGrid("setGridParam", { search: sd })
  10306. .trigger("reloadGrid", [$.extend({ page: 1 }, o.reloadGridResetOptions || {})]);
  10307. }
  10308. }
  10309. if (saveurl) { $self.jqGrid("setGridParam", { url: saveurl }); }
  10310. $self.triggerHandler("jqGridToolbarAfterClear");
  10311. if ($.isFunction(o.afterClear)) { o.afterClear.call($t); }
  10312. },
  10313. toggleToolbar = function () {
  10314. var trow = $("tr.ui-search-toolbar", grid.hDiv),
  10315. trow2 = p.frozenColumns === true ? $("tr.ui-search-toolbar", grid.fhDiv) : false;
  10316. if (trow.css("display") === "none") {
  10317. trow.show();
  10318. if (trow2) {
  10319. trow2.show();
  10320. }
  10321. } else {
  10322. trow.hide();
  10323. if (trow2) {
  10324. trow2.hide();
  10325. }
  10326. }
  10327. if (p.frozenColumns === true) {
  10328. $self.jqGrid("destroyFrozenColumns");
  10329. $self.jqGrid("setFrozenColumns");
  10330. }
  10331. },
  10332. odata = getRes("search.odata") || [],
  10333. customSortOperations = p.customSortOperations,
  10334. buildRuleMenu = function (elem, left, top) {
  10335. $("#sopt_menu").remove();
  10336. left = parseInt(left, 10);
  10337. top = parseInt(top, 10) + 18;
  10338. var selclass, ina, i = 0, aoprs = [], selected = $(elem).data("soper"), nm = $(elem).data("colname"),
  10339. fs = $(".ui-jqgrid-view").css("font-size") || "11px",
  10340. str = "<ul id='sopt_menu' class='" +
  10341. getGuiStyles.call($t, "searchToolbar.menu", "ui-search-menu") +
  10342. "' role='menu' tabindex='0' style='z-index:9999;display:block;font-size:" + fs + ";left:" + left + "px;top:" + top + "px;'>";
  10343. i = p.iColByName[nm];
  10344. if (i === undefined) { return; }
  10345. var cm = colModel[i], options = $.extend({}, cm.searchoptions), odataItem, item, itemOper, itemOperand, itemText;
  10346. if (!options.sopt) {
  10347. options.sopt = [];
  10348. options.sopt[0] = (cm.stype === "select" || cm.stype === "checkbox") ? "eq" : o.defaultSearch;
  10349. }
  10350. $.each(odata, function () { aoprs.push(this.oper); });
  10351. // append aoprs array with custom operations defined in customSortOperations parameter jqGrid
  10352. if (customSortOperations != null) {
  10353. $.each(customSortOperations, function (propertyName) { aoprs.push(propertyName); });
  10354. }
  10355. for (i = 0; i < options.sopt.length; i++) {
  10356. itemOper = options.sopt[i];
  10357. ina = $.inArray(itemOper, aoprs);
  10358. if (ina !== -1) {
  10359. odataItem = odata[ina];
  10360. if (odataItem !== undefined) {
  10361. // standard operation
  10362. itemOperand = o.operands[itemOper];
  10363. itemText = odataItem.text;
  10364. } else if (customSortOperations != null) {
  10365. // custom operation
  10366. item = customSortOperations[itemOper];
  10367. itemOperand = item.operand;
  10368. itemText = item.text;
  10369. }
  10370. selclass = selected === itemOper ? highlightClass : "";
  10371. str += '<li class="' +
  10372. getGuiStyles.call($t, "searchToolbar.menuItem", "ui-jqgrid-menu-item " + selclass) +
  10373. '" role="presentation"><a class="' +
  10374. getGuiStyles.call($t, "searchToolbar.menuItemButton", "g-menu-item") +
  10375. '" tabindex="0" role="menuitem" value="' + htmlEncode(itemOper) + '" data-oper="' + htmlEncode(itemOperand) + '"><table><tr><td style="width:25px">' + htmlEncode(itemOperand) + '</td><td>' + htmlEncode(itemText) + '</td></tr></table></a></li>';
  10376. }
  10377. }
  10378. str += "</ul>";
  10379. $("body").append(str);
  10380. $("#sopt_menu > li > a").hover(
  10381. function () { $(this).addClass(hoverClasses); },
  10382. function () { $(this).removeClass(hoverClasses); }
  10383. ).click(function () {
  10384. var v = $(this).attr("value"),
  10385. oper = $(this).data("oper");
  10386. $self.triggerHandler("jqGridToolbarSelectOper", [v, oper, elem]);
  10387. $("#sopt_menu").hide();
  10388. $(elem).data("soper", v).text(oper);
  10389. if (o.autosearch === true) {
  10390. var inpelm = $(elem).parent().next().children()[0];
  10391. if ($(inpelm).val() || v === "nu" || v === "nn" || $.inArray(v, p.customUnaryOperations) >= 0) {
  10392. triggerToolbar();
  10393. }
  10394. }
  10395. });
  10396. },
  10397. timeoutHnd,
  10398. bindings = [],
  10399. $tr = $("<tr></tr>", { "class": "ui-search-toolbar", role: "row form" });
  10400. if (o.loadFilterDefaults) {
  10401. currentFilters = parseFilter() || {};
  10402. }
  10403. // create the row
  10404. $.each(colModel, function (ci) {
  10405. var cm = this, soptions, mode = "filter", surl, sot, so, i, searchoptions = cm.searchoptions || {}, editoptions = cm.editoptions || {},
  10406. $th = $("<th></th>", {
  10407. "class": getGuiStyles.call($t, "colHeaders", "ui-th-column ui-th-" + p.direction + " " + (o.applyLabelClasses ? cm.labelClasses || "" : "")),
  10408. role: "gridcell",
  10409. "aria-describedby": p.id + "_" + cm.name
  10410. }),
  10411. $thd = $("<div></div>"), elem, $elem,
  10412. $stable = $("<table class='ui-search-table'><tbody><tr><td class='ui-search-oper'></td><td class='ui-search-input'></td><td class='ui-search-clear' style='width:1px'></td></tr></tbody></table>"),
  10413. $tds = $stable.children("tbody").children("tr").children("td"),
  10414. $tdOper = $tds.eq(0),
  10415. $tdInput = $tds.eq(1),
  10416. $tdClear = $tds.eq(2);
  10417. if (this.hidden === true) { $th.css("display", "none"); }
  10418. this.search = this.search === false ? false : true;
  10419. if (this.stype === undefined) { this.stype = "text"; }
  10420. soptions = $.extend({ mode: mode, name: cm.name, cm: cm, iCol: ci, id: getId(cm.name) }, searchoptions);
  10421. if (this.search) {
  10422. if (o.searchOperators) {
  10423. if (p.search && currentFilters[this.name] != null) {
  10424. so = currentFilters[this.name].op;
  10425. } else {
  10426. so = (soptions.sopt) ? soptions.sopt[0] : (cm.stype === "select" || cm.stype === "checkbox") ? "eq" : o.defaultSearch;
  10427. }
  10428. for (i = 0; i < odata.length; i++) {
  10429. if (odata[i].oper === so) {
  10430. sot = o.operands[so] || "";
  10431. break;
  10432. }
  10433. }
  10434. if (sot === undefined && customSortOperations != null) {
  10435. var customOp;
  10436. for (customOp in customSortOperations) {
  10437. if (customSortOperations.hasOwnProperty(customOp) && customOp === so) {
  10438. sot = customSortOperations[customOp].operand;
  10439. break;
  10440. //soptions.searchtitle = customSortOperations[customOp].title;
  10441. }
  10442. }
  10443. }
  10444. if (sot === undefined) { sot = "="; }
  10445. $tdOper.append("<a title='" +
  10446. (soptions.searchtitle != null ? soptions.searchtitle : getRes("search.operandTitle")) +
  10447. "' data-soper='" + so + "' class='" +
  10448. getGuiStyles.call($t, "searchToolbar.operButton", "soptclass") +
  10449. "' data-colname='" + this.name + "'>" + htmlEncode(sot) + "</a>");
  10450. }
  10451. $tdOper.data("colindex", ci);
  10452. if (soptions.sopt == null || soptions.sopt.length === 1) {
  10453. $tdOper.hide();
  10454. }
  10455. if (p.search && currentFilters[this.name] != null) {
  10456. soptions.defaultValue = currentFilters[this.name].data;
  10457. }
  10458. if (soptions.clearSearch === undefined) {
  10459. soptions.clearSearch = this.stype === "text" ? true : false;
  10460. }
  10461. if (soptions.clearSearch) {
  10462. var csv = $.isFunction(o.resetTitle) ?
  10463. o.resetTitle.call($t, {
  10464. options: o,
  10465. cm: cm,
  10466. cmName: cm.name,
  10467. iCol: ci
  10468. }) :
  10469. (getRes("search.resetTitle") || "Clear Search Value") + " " + jgrid.stripHtml(p.colNames[ci]);
  10470. $tdClear.append("<a title='" + csv + "' aria-label='" + csv + "' class='" +
  10471. getGuiStyles.call($t, "searchToolbar.clearButton", "clearsearchclass") +
  10472. "'><span>" + o.resetIcon + "</span></a>");
  10473. } else {
  10474. $tdClear.hide();
  10475. }
  10476. $thd.append($stable);
  10477. switch (this.stype) {
  10478. case "checkbox":
  10479. var state = soptions.defaultValue !== undefined ? soptions.defaultValue : "-1";
  10480. $elem = $("<input role='search' type='checkbox' class='" + dataFieldClass +
  10481. "' name='" + (cm.index || cm.name) +
  10482. "' id='" + getId(cm.name) +
  10483. "' aria-labelledby='" + "jqgh_" + p.id + "_" + cm.name +
  10484. "' data-state='" + state + "'/>");
  10485. if (state === "-1") {
  10486. $elem.prop("indeterminate", true);
  10487. } else if (state === "1") {
  10488. $elem.prop("checked", true);
  10489. }
  10490. $elem.click(function () {
  10491. var $checkbox = $(this);
  10492. switch ($checkbox.data("state")) {
  10493. case -1: // has indeterminate state
  10494. // make checked
  10495. setThreeStateCheckbox($checkbox, 1);
  10496. break;
  10497. case 0: // is unchecked
  10498. // set indeterminate state
  10499. setThreeStateCheckbox($checkbox, -1);
  10500. break;
  10501. default: // is checked
  10502. // make unchecked
  10503. setThreeStateCheckbox($checkbox, 0);
  10504. break;
  10505. }
  10506. if (o.autosearch === true) {
  10507. triggerToolbar();
  10508. }
  10509. });
  10510. $tdInput.append($elem);
  10511. if (soptions.attr) { $elem.attr(soptions.attr); }
  10512. bindings.push({ elem: $elem[0], options: soptions }); break;
  10513. case "select":
  10514. surl = this.surl || soptions.dataUrl;
  10515. if (surl) {
  10516. // data returned should have already constructed html select
  10517. // primitive jQuery load
  10518. $.ajax($.extend({
  10519. url: surl,
  10520. context: { $tdInput: $tdInput, options: soptions, cm: cm, iCol: ci },
  10521. dataType: "html",
  10522. success: function (data, textStatus, jqXHR) {
  10523. var cm1 = this.cm, iCol1 = this.iCol, soptions1 = this.options, d, ov1,
  10524. $td = this.$tdInput, $select;
  10525. if (soptions1.buildSelect !== undefined) {
  10526. d = soptions1.buildSelect.call($t, data, jqXHR, cm1, iCol1);
  10527. if (d) {
  10528. $td.append(d);
  10529. }
  10530. } else {
  10531. $td.append(data);
  10532. }
  10533. $select = $td.children("select");
  10534. $select.attr({ name: cm1.index || cm1.name, id: getId(cm1.name) });
  10535. if (soptions1.attr) { $select.attr(soptions1.attr); }
  10536. $select.addClass(dataFieldClass);
  10537. $select.css({ width: "100%" });
  10538. if ($select.find("option[value='']").length === 0 && typeof soptions.noFilterText === "string") {
  10539. ov1 = document.createElement("option");
  10540. ov1.value = "";
  10541. ov1.innerHTML = soptions.noFilterText;
  10542. $select.prepend(ov1);
  10543. if ($($select[0].options[$select[0].selectedIndex]).attr("selected") == null && !$select[0].multiple) {
  10544. $select[0].selectedIndex = 0;
  10545. }
  10546. }
  10547. if ($select[0].multiple && $select.find("option[selected]").length === 0 && $select[0].selectedIndex !== -1) {
  10548. // It can be that multiselect (select with multiple attribute) will be returned from surl
  10549. // or build with respect of buildSelect WITHOUT having multiple attribute
  10550. // (just as <select>...</select> instead of <select multiple="multiple">...</select>)
  10551. // and the multiple attribute will be assigned via soptions.attr (attr: { multiple: "multiple" }).
  10552. // One will have non-multiple select initially, where the first element will be automatically selected.
  10553. // After assigning the attribute multiple="multiple" the select will be able to have no selected elements,
  10554. // but it will be too late. To fix the case we will unselect the first element in the special case.
  10555. $select[0].options[$select[0].selectedIndex].selected = false;
  10556. }
  10557. if (soptions1.defaultValue !== undefined) { $select.val(soptions1.defaultValue); }
  10558. // preserve autoserch
  10559. jgrid.bindEv.call($t, $select[0], soptions1);
  10560. jgrid.fullBoolFeedback.call($t, soptions1.selectFilled, "jqGridSelectFilled", {
  10561. elem: $select[0],
  10562. options: soptions1,
  10563. cm: cm1,
  10564. cmName: cm1.name,
  10565. iCol: iCol1,
  10566. mode: mode
  10567. });
  10568. if (o.autosearch === true) {
  10569. $select.change(function () {
  10570. triggerToolbar();
  10571. return false;
  10572. });
  10573. }
  10574. }
  10575. }, jgrid.ajaxOptions, p.ajaxSelectOptions || {}));
  10576. } else {
  10577. var oSv, sep, delim;
  10578. if (cm.searchoptions) {
  10579. oSv = searchoptions.value === undefined ? editoptions.value || "" : searchoptions.value;
  10580. sep = searchoptions.separator === undefined ? editoptions.separator || ":" : searchoptions.separator;
  10581. delim = searchoptions.delimiter === undefined ? editoptions.delimiter || ";" : searchoptions.delimiter;
  10582. } else if (cm.editoptions) {
  10583. oSv = editoptions.value === undefined ? "" : editoptions.value;
  10584. sep = editoptions.separator === undefined ? ":" : editoptions.separator;
  10585. delim = editoptions.delimiter === undefined ? ";" : editoptions.delimiter;
  10586. }
  10587. if (searchoptions.generateValue && p.indexByColumnData[cm.name] != null) {
  10588. oSv = $t.generateValueFromColumnIndex(cm.name, sep, delim);
  10589. }
  10590. if (oSv) {
  10591. elem = document.createElement("select");
  10592. elem.style.width = "100%";
  10593. $elem = $(elem).attr({
  10594. name: cm.index || cm.name,
  10595. role: "search",
  10596. id: getId(cm.name),
  10597. "aria-describedby": p.id + "_" + cm.name
  10598. });
  10599. if (soptions.attr) { $elem.attr(soptions.attr); }
  10600. var isNoFilterValueExist = jgrid.fillSelectOptions(
  10601. elem,
  10602. oSv,
  10603. sep,
  10604. delim,
  10605. soptions.attr != null && soptions.attr.multiple
  10606. );
  10607. if (!isNoFilterValueExist && typeof soptions.noFilterText === "string") {
  10608. var ov = document.createElement("option");
  10609. ov.value = "";
  10610. ov.innerHTML = soptions.noFilterText;
  10611. ov.selected = true;
  10612. $elem.prepend(ov);
  10613. }
  10614. if (soptions.defaultValue !== undefined) { $elem.val(soptions.defaultValue); }
  10615. $elem.addClass(dataFieldClass);
  10616. //bindEv.call($t, elem, soptions);
  10617. bindings.push({ elem: elem, options: soptions });
  10618. $tdInput.append(elem);
  10619. jgrid.fullBoolFeedback.call($t, soptions.selectFilled, "jqGridSelectFilled", {
  10620. elem: elem,
  10621. options: cm.searchoptions || editoptions,
  10622. cm: cm,
  10623. cmName: cm.name,
  10624. iCol: ci,
  10625. mode: mode
  10626. });
  10627. if (o.autosearch === true) {
  10628. $elem.change(function () {
  10629. triggerToolbar();
  10630. return false;
  10631. });
  10632. }
  10633. }
  10634. }
  10635. break;
  10636. case "text":
  10637. $elem = $("<input role='search' type='text' class='" + dataFieldClass +
  10638. "' name='" + (cm.index || cm.name) +
  10639. "' id='" + getId(cm.name) +
  10640. "' aria-labelledby='" + "jqgh_" + p.id + "_" + cm.name +
  10641. "' value='" + (soptions.defaultValue !== undefined ? soptions.defaultValue : "") + "'/>");
  10642. $tdInput.append($elem);
  10643. if (cm.createColumnIndex && soptions.generateDatalist) {
  10644. var dataListId = "dl_" + getId(cm.name),
  10645. $datalist = $self.jqGrid("generateDatalistFromColumnIndex", cm.name);
  10646. if ($datalist != null && $datalist.length > 0) {
  10647. $elem.attr("list", dataListId);
  10648. $tdInput.append($datalist.attr("id", dataListId));
  10649. }
  10650. }
  10651. if (soptions.attr) { $elem.attr(soptions.attr); }
  10652. bindings.push({ elem: $elem[0], options: soptions });
  10653. if (o.autosearch === true) {
  10654. if (o.searchOnEnter) {
  10655. $elem.keypress(function (e) {
  10656. var key1 = e.charCode || e.keyCode || 0;
  10657. if (key1 === 13) {
  10658. triggerToolbar();
  10659. return false;
  10660. }
  10661. return this;
  10662. });
  10663. } else {
  10664. $elem.keydown(function (e) {
  10665. var key1 = e.which;
  10666. switch (key1) {
  10667. case 13:
  10668. return false;
  10669. case 9:
  10670. case 16:
  10671. case 37:
  10672. case 38:
  10673. case 39:
  10674. case 40:
  10675. case 27:
  10676. break;
  10677. default:
  10678. if (timeoutHnd) { clearTimeout(timeoutHnd); }
  10679. timeoutHnd = setTimeout(function () { triggerToolbar(); }, o.autosearchDelay);
  10680. }
  10681. });
  10682. }
  10683. }
  10684. break;
  10685. case "custom":
  10686. $tdInput.append("<span style='width:100%;padding:0;box-sizing:border-box;' name='" + (cm.index || cm.name) + "' id='" + getId(cm.name) + "'/>");
  10687. try {
  10688. if ($.isFunction(soptions.custom_element)) {
  10689. var celm = soptions.custom_element.call($t, soptions.defaultValue !== undefined ? soptions.defaultValue : "", soptions);
  10690. if (celm) {
  10691. celm = $(celm).addClass("customelement");
  10692. $thd.find("span[name='" + (cm.index || cm.name) + "']").append(celm);
  10693. } else {
  10694. throw "e2";
  10695. }
  10696. } else {
  10697. throw "e1";
  10698. }
  10699. } catch (ex) {
  10700. if (ex === "e1") {
  10701. infoDialog.call($t, errcap, "function 'custom_element' " + editMsg.nodefined, bClose);
  10702. }
  10703. if (ex === "e2") {
  10704. infoDialog.call($t, errcap, "function 'custom_element' " + editMsg.novalue, bClose);
  10705. } else {
  10706. infoDialog.call($t, errcap, typeof ex === "string" ? ex : ex.message, bClose);
  10707. }
  10708. }
  10709. break;
  10710. }
  10711. }
  10712. $th.append($thd);
  10713. $th.find(".ui-search-oper .soptclass,.ui-search-clear .clearsearchclass")
  10714. .hover(function () {
  10715. $(this).addClass(hoverClasses);
  10716. }, function () {
  10717. $(this).removeClass(hoverClasses);
  10718. });
  10719. $tr.append($th);
  10720. if (!o.searchOperators) {
  10721. $tdOper.hide();
  10722. }
  10723. });
  10724. $(grid.hDiv).find(">div>.ui-jqgrid-htable>thead").append($tr);
  10725. $.each(bindings, function () {
  10726. jgrid.bindEv.call($t, this.elem, this.options);
  10727. });
  10728. if (o.searchOperators) {
  10729. $(".soptclass", $tr).click(function (e) {
  10730. var offset = $(this).offset(),
  10731. left = (offset.left),
  10732. top = (offset.top);
  10733. buildRuleMenu(this, left, top);
  10734. e.stopPropagation();
  10735. });
  10736. $("body").on("click", function (e) {
  10737. if (e.target.className !== "soptclass") {
  10738. $("#sopt_menu").hide();
  10739. }
  10740. });
  10741. }
  10742. $(".clearsearchclass", $tr).click(function () {
  10743. var $tdOper = $(this).closest(".ui-search-clear"),
  10744. $tdSearchOper = $tdOper.siblings(".ui-search-oper"),
  10745. $oper = $tdSearchOper.children("a"),
  10746. soper = $oper.data("soper"), v, operText,
  10747. coli = parseInt($tdSearchOper.data("colindex"), 10),
  10748. $tdInput = $tdOper.siblings(".ui-search-input"),
  10749. cm = colModel[coli],
  10750. sval = $.extend({}, cm.searchoptions || {}),
  10751. dval = sval.defaultValue || "";
  10752. switch (cm.stype) {
  10753. case "select":
  10754. if (dval) {
  10755. $tdInput.find("select").val(dval);
  10756. } else {
  10757. $tdInput.find("select")[0].selectedIndex = 0;
  10758. }
  10759. break;
  10760. case "checkbox":
  10761. // set indeterminate state
  10762. setThreeStateCheckbox($tdInput.find("input[type=checkbox]"), -1);
  10763. break;
  10764. default:
  10765. $tdInput.find("input").val(dval);
  10766. break;
  10767. }
  10768. if (soper === "nu" || soper === "nn" || $.inArray(soper, p.customUnaryOperations) >= 0) {
  10769. // one need reset an unary operation to default search operation
  10770. v = sval.sopt ?
  10771. sval.sopt[0] :
  10772. (cm.stype === "select" || cm.stype === "checkbox") ?
  10773. "eq" :
  10774. o.defaultSearch;
  10775. operText = customSortOperations != null && customSortOperations[v] != null ?
  10776. customSortOperations[v].operand :
  10777. o.operands[v] || "";
  10778. $oper.data("soper", v).text(operText);
  10779. }
  10780. // ToDo custom search type
  10781. if (o.autosearch === true) {
  10782. triggerToolbar();
  10783. }
  10784. });
  10785. $t.ftoolbar = true;
  10786. $t.triggerToolbar = triggerToolbar;
  10787. $t.clearToolbar = clearToolbar;
  10788. $t.toggleToolbar = toggleToolbar;
  10789. if (p.frozenColumns === true) {
  10790. $self.jqGrid("destroyFrozenColumns");
  10791. $self.jqGrid("setFrozenColumns");
  10792. }
  10793. $self.on(
  10794. "jqGridRefreshFilterValues.filterToolbar" + (o.loadFilterDefaults ? " jqGridAfterLoadComplete.filterToolbar" : ""),
  10795. function () {
  10796. var cmName, filter, newFilters = parseFilter(true) || {}, $input, $searchOper, i, $th, searchoptions;
  10797. if (!o.stringResult && !o.searchOperators && p.datatype !== "local" && p.search) {
  10798. return; // do nothing on legacy searching
  10799. }
  10800. for (cmName in newFilters) {
  10801. if (newFilters.hasOwnProperty(cmName)) {
  10802. filter = newFilters[cmName];
  10803. $input = $(getIdSel(cmName));
  10804. $th = $input.closest("th.ui-th-column");
  10805. if ($input.length > 0 && $th.length > 0) {
  10806. searchoptions = (p.colModel[$th[0].cellIndex] || {}).searchoptions || {};
  10807. if ($input[0].tagName.toUpperCase() === "SELECT" && $input[0].multiple) {
  10808. $input.val(filter.data.split(p.inFilterSeparator || ","));
  10809. } else if ($input.is("input[type=checkbox]")) {
  10810. var onOffValue = getOnOffValue(searchoptions);
  10811. setThreeStateCheckbox(
  10812. $input,
  10813. filter.data === onOffValue.on ?
  10814. 1 :
  10815. (filter.data === onOffValue.off ? 0 : -1)
  10816. );
  10817. } else if ($input.find(".customelement").length > 0 && $.isFunction(searchoptions.custom_value)) {
  10818. var oldValue = searchoptions.custom_value.call($t, $input.find(".customelement").first(), "get");
  10819. if (filter.data === "" && searchoptions.defaultValue !== undefined) {
  10820. filter.data = searchoptions.defaultValue;
  10821. }
  10822. if (oldValue === undefined) {
  10823. oldValue = "";
  10824. }
  10825. if (filter.data !== oldValue && String(filter.data) !== String(oldValue)) {
  10826. searchoptions.custom_value.call($t, $input.find(".customelement").first(), "set", filter.data);
  10827. }
  10828. } else {
  10829. if (filter.data === "" && searchoptions.defaultValue !== undefined) {
  10830. filter.data = searchoptions.defaultValue;
  10831. }
  10832. if ($.trim($input.val()) !== String(filter.data)) {
  10833. $input.val(filter.data);
  10834. }
  10835. }
  10836. $searchOper = $input.closest(".ui-search-input")
  10837. .siblings(".ui-search-oper")
  10838. .children(".soptclass");
  10839. $searchOper.data("soper", filter.op);
  10840. $searchOper.text(o.operands[filter.op] || (p.customSortOperations[filter.op] || {}).operand);
  10841. }
  10842. }
  10843. }
  10844. for (i = 0; i < p.colModel.length; i++) {
  10845. cmName = p.colModel[i].name;
  10846. if (!newFilters.hasOwnProperty(cmName)) {
  10847. $(getIdSel(cmName)).val("");
  10848. }
  10849. }
  10850. }
  10851. );
  10852. });
  10853. },
  10854. destroyFilterToolbar: function () {
  10855. return this.each(function () {
  10856. var self = this;
  10857. if (!self.ftoolbar) {
  10858. return;
  10859. }
  10860. self.triggerToolbar = null;
  10861. self.clearToolbar = null;
  10862. self.toggleToolbar = null;
  10863. self.ftoolbar = false;
  10864. $(self.grid.hDiv).find("table thead tr.ui-search-toolbar").remove();
  10865. if (self.p.frozenColumns === true) {
  10866. $(self).jqGrid("destroyFrozenColumns")
  10867. .jqGrid("setFrozenColumns");
  10868. }
  10869. });
  10870. },
  10871. destroyGroupHeader: function (nullHeader) {
  10872. if (nullHeader === undefined) {
  10873. nullHeader = true;
  10874. }
  10875. return this.each(function () {
  10876. var $t = this, i, l, $th, $resizing, grid = $t.grid, cm = $t.p.colModel, hc,
  10877. thead = $("table.ui-jqgrid-htable thead", grid.hDiv);
  10878. if (!grid) { return; }
  10879. $($t).off(".setGroupHeaders");
  10880. var $tr = $("<tr>", { role: "row" }).addClass("ui-jqgrid-labels");
  10881. var headers = grid.headers;
  10882. for (i = 0, l = headers.length; i < l; i++) {
  10883. hc = cm[i].hidden ? "none" : "";
  10884. $th = $(headers[i].el)
  10885. .width(headers[i].width)
  10886. .css("display", hc);
  10887. try {
  10888. $th.removeAttr("rowSpan");
  10889. } catch (rs) {
  10890. //IE 6/7
  10891. $th.attr("rowSpan", 1);
  10892. }
  10893. $tr.append($th);
  10894. $resizing = $th.children("span.ui-jqgrid-resize");
  10895. if ($resizing.length > 0) {// resizable column
  10896. $resizing[0].style.height = "";
  10897. }
  10898. $th.children("div")[0].style.top = "";
  10899. }
  10900. $(thead).children("tr.ui-jqgrid-labels").remove();
  10901. $(thead).prepend($tr);
  10902. if (nullHeader === true) {
  10903. $($t).jqGrid("setGridParam", { "groupHeader": null });
  10904. }
  10905. });
  10906. },
  10907. setGroupHeaders: function (o) {
  10908. o = $.extend({
  10909. useColSpanStyle: false,
  10910. applyLabelClasses: true,
  10911. groupHeaders: []
  10912. }, o || {});
  10913. return this.each(function () {
  10914. this.p.groupHeader = o;
  10915. var ts = this, i, cmi, skip = 0, $tr, $colHeader, th, $th, thStyle, iCol, cghi, numberOfColumns, titleText, cVisibleColumns,
  10916. p = ts.p, colModel = p.colModel, cml = colModel.length, ths = ts.grid.headers, $theadInTable, thClasses,
  10917. $htable = $("table.ui-jqgrid-htable", ts.grid.hDiv), isCellClassHidden = jgrid.isCellClassHidden,
  10918. $trLabels = $htable.children("thead").children("tr.ui-jqgrid-labels"),
  10919. $trLastWithLabels = $trLabels.last().addClass("jqg-second-row-header"),
  10920. $thead = $htable.children("thead"),
  10921. $firstHeaderRow = $htable.find(".jqg-first-row-header");
  10922. if ($firstHeaderRow[0] === undefined) {
  10923. $firstHeaderRow = $("<tr>", { role: "row", "aria-hidden": "true" }).addClass("jqg-first-row-header").css("height", "auto");
  10924. } else {
  10925. $firstHeaderRow.empty();
  10926. }
  10927. var inColumnHeader = function (cmName, columnHeaders) {
  10928. var j;
  10929. for (j = 0; j < columnHeaders.length; j++) {
  10930. if (columnHeaders[j].startColumnName === cmName) {
  10931. return columnHeaders[j];
  10932. }
  10933. }
  10934. return 0; // falsy value
  10935. };
  10936. $(ts).prepend($thead);
  10937. $tr = $("<tr>", { role: "row" }).addClass("ui-jqgrid-labels jqg-third-row-header");
  10938. for (i = 0; i < cml; i++) {
  10939. th = ths[i].el;
  10940. $th = $(th);
  10941. cmi = colModel[i];
  10942. // build the next cell for the first header row
  10943. // ??? cmi.hidden || isCellClassHidden(cmi.classes) || $th.is(":hidden")
  10944. thStyle = { height: "0", width: ths[i].width + "px", display: (cmi.hidden ? "none" : "") };
  10945. $("<th>", { role: "gridcell" }).css(thStyle).addClass("ui-first-th-" + p.direction + (o.applyLabelClasses ? " " + (cmi.labelClasses || "") : "")).appendTo($firstHeaderRow);
  10946. th.style.width = ""; // remove unneeded style
  10947. thClasses = getGuiStyles.call(ts, "colHeaders", "ui-th-column-header ui-th-" + p.direction + " " + (o.applyLabelClasses ? cmi.labelClasses || "" : ""));
  10948. cghi = inColumnHeader(cmi.name, o.groupHeaders);
  10949. if (cghi) {
  10950. numberOfColumns = cghi.numberOfColumns;
  10951. titleText = cghi.titleText;
  10952. // caclulate the number of visible columns from the next numberOfColumns columns
  10953. for (cVisibleColumns = 0, iCol = 0; iCol < numberOfColumns && (i + iCol < cml); iCol++) {
  10954. if (!colModel[i + iCol].hidden && !isCellClassHidden(colModel[i + iCol].classes)) {
  10955. cVisibleColumns++;
  10956. }
  10957. }
  10958. // The next numberOfColumns headers will be moved in the next row
  10959. // in the current row will be placed the new column header with the titleText.
  10960. // The text will be over the cVisibleColumns columns
  10961. $colHeader = $("<th>")
  10962. .addClass(thClasses)
  10963. .html(titleText || "&nbsp;");
  10964. if (cVisibleColumns > 0) {
  10965. $colHeader.attr("colspan", String(cVisibleColumns));
  10966. }
  10967. if (p.headertitles) {
  10968. $colHeader.attr("title", $colHeader.text());
  10969. }
  10970. // hide if not a visible cols
  10971. if (cVisibleColumns === 0) {
  10972. $colHeader.hide();
  10973. }
  10974. $th.before($colHeader); // insert new column header before the current
  10975. $tr.append(th); // move the current header in the next row
  10976. // set the counter of headers which will be moved in the next row
  10977. skip = numberOfColumns - 1;
  10978. } else {
  10979. if (skip === 0) {
  10980. if (o.useColSpanStyle) {
  10981. // expand the header height to two rows
  10982. $th.attr("rowspan", $trLabels.length + 1); // consider to use ($th.attr("rowspan") || 1) instead of $trLabels.length
  10983. } else {
  10984. $("<th>")
  10985. .addClass(thClasses)
  10986. .css({ "display": cmi.hidden ? "none" : "", "border-top": "0 none" })
  10987. .insertBefore($th);
  10988. $tr.append(th);
  10989. }
  10990. } else {
  10991. // move the header to the next row
  10992. $tr.append(th);
  10993. skip--;
  10994. }
  10995. }
  10996. }
  10997. $theadInTable = $(ts).children("thead");
  10998. $theadInTable.prepend($firstHeaderRow);
  10999. $tr.insertAfter($trLastWithLabels);
  11000. $htable.prepend($theadInTable);
  11001. $(ts).triggerHandler("jqGridAfterSetGroupHeaders");
  11002. });
  11003. },
  11004. getNumberOfFrozenColumns: function () {
  11005. var $t = this;
  11006. if ($t.length === 0) {
  11007. return 0;
  11008. }
  11009. $t = $t[0];
  11010. var colModel = $t.p.colModel, len = colModel.length, maxfrozen = -1, i;
  11011. // get the max index of frozen col
  11012. for (i = 0; i < len; i++) {
  11013. // from left, no breaking frozen
  11014. if (colModel[i].frozen !== true) {
  11015. break;
  11016. }
  11017. maxfrozen = i;
  11018. }
  11019. return maxfrozen + 1;
  11020. },
  11021. setFrozenColumns: function (o) {
  11022. o = o || {};
  11023. return this.each(function () {
  11024. var $t = this, $self = $($t), p = $t.p, grid = $t.grid;
  11025. if (!grid || p == null || p.frozenColumns === true) { return; }
  11026. var cm = p.colModel, i, len = cm.length, maxfrozen = -1, frozen = false, frozenIds = [], $colHeaderRow,// nonFrozenIds = [],
  11027. tid = jqID(p.id), // one can use p.idSel and remove "#"
  11028. hoverClasses = getGuiStyles.call($t, "states.hover");
  11029. // TODO treeGrid and grouping Support
  11030. // TODO: allow to edit columns AFTER frozen columns
  11031. if (p.subGrid === true || p.treeGrid === true || p.scroll) {
  11032. return;
  11033. }
  11034. // get the max index of frozen col
  11035. for (i = 0; i < len; i++) {
  11036. // from left, no breaking frozen
  11037. if (cm[i].frozen !== true) {
  11038. break;
  11039. //nonFrozenIds.push("#jqgh_" + tid + "_" + jqID(cm[i].name));
  11040. }
  11041. frozen = true;
  11042. maxfrozen = i;
  11043. frozenIds.push("#jqgh_" + tid + "_" + jqID(cm[i].name));
  11044. }
  11045. if (p.sortable) {
  11046. $colHeaderRow = $(grid.hDiv).find(".ui-jqgrid-htable .ui-jqgrid-labels");
  11047. try {
  11048. $colHeaderRow.sortable("destroy");
  11049. } catch (ignore) { }
  11050. $self.jqGrid("setGridParam", {
  11051. sortable: {
  11052. options: {
  11053. items: frozenIds.length > 0 ?
  11054. ">th:not(:has(" + frozenIds.join(",") + "),:hidden)" :
  11055. ">th:not(:hidden)"
  11056. }
  11057. }
  11058. });
  11059. $self.jqGrid("sortableColumns", $colHeaderRow);
  11060. }
  11061. if (maxfrozen >= 0 && frozen) {
  11062. var top = p.caption ? $(grid.cDiv).outerHeight() : 0,
  11063. hth = $(".ui-jqgrid-htable", p.gView).height();
  11064. //headers
  11065. if (p.toppager) {
  11066. top = top + $(grid.topDiv).outerHeight();
  11067. }
  11068. if (p.toolbar[0] === true) {
  11069. if (p.toolbar[1] !== "bottom") {
  11070. top = top + $(grid.uDiv).outerHeight();
  11071. }
  11072. }
  11073. grid.fhDiv = $("<div style='position:absolute;overflow:hidden;" +
  11074. (p.direction === "rtl" ? "right:0;border-top-left-radius:0;" : "left:0;border-top-right-radius:0;") +
  11075. "top:" + top + "px;height:" + hth +
  11076. "px;' class='" + getGuiStyles.call($t, "hDiv", "frozen-div ui-jqgrid-hdiv") + "'></div>");
  11077. grid.fbDiv = $("<div style='position:absolute;overflow:hidden;" +
  11078. (p.direction === "rtl" ? "right:0;" : "left:0;") +
  11079. "top:" + (parseInt(top, 10) + parseInt(hth, 10) + 1) +
  11080. "px;overflow:hidden;' class='frozen-bdiv ui-jqgrid-bdiv'></div>");
  11081. $(p.gView).append(grid.fhDiv);
  11082. var htbl = $(".ui-jqgrid-htable", p.gView).clone(true),
  11083. tHeadRows = htbl[0].tHead.rows;
  11084. // groupheader support - only if useColSpanstyle is false
  11085. if (p.groupHeader) {
  11086. // TODO: remove all th which corresponds non-frozen columns. One can identify there by id
  11087. // for example. Consider to use name attribute of th on column headers. It simplifies
  11088. // identifying of the columns.
  11089. $(tHeadRows[0].cells).filter(":gt(" + maxfrozen + ")").remove();
  11090. $(tHeadRows).filter(".jqg-third-row-header").each(function () {
  11091. $(this).children("th[id]")
  11092. .each(function () {
  11093. var id = $(this).attr("id"), colName;
  11094. if (id && id.substr(0, $t.id.length + 1) === $t.id + "_") {
  11095. colName = id.substr($t.id.length + 1);
  11096. if (p.iColByName[colName] > maxfrozen) {
  11097. $(this).remove();
  11098. }
  11099. }
  11100. });
  11101. });
  11102. var swapfroz = -1, fdel = -1, cs, rs;
  11103. // TODO: test carefully processing of hidden columns
  11104. $(tHeadRows).filter(".jqg-second-row-header").children("th").each(function () {
  11105. cs = parseInt($(this).attr("colspan") || 1, 10);
  11106. rs = parseInt($(this).attr("rowspan") || 1, 10);
  11107. if (rs > 1) {
  11108. swapfroz++;
  11109. fdel++;
  11110. } else if (cs) {
  11111. swapfroz = swapfroz + cs;
  11112. fdel++;
  11113. }
  11114. if (swapfroz === maxfrozen) {
  11115. return false;
  11116. }
  11117. });
  11118. if (swapfroz !== maxfrozen) {
  11119. fdel = maxfrozen;
  11120. }
  11121. $(tHeadRows).filter(".jqg-second-row-header,.ui-search-toolbar").each(function () {
  11122. $(this).children(":gt(" + fdel + ")").remove();
  11123. });
  11124. } else {
  11125. $(tHeadRows).each(function () {
  11126. $(this).children(":gt(" + maxfrozen + ")").remove();
  11127. });
  11128. }
  11129. // htable, bdiv and ftable uses table-layout:fixed; style
  11130. // to make it working one have to set ANY width value on table.
  11131. // The value of the width will be ignored, the sum of widths
  11132. // of the first column will be used as the width of tables
  11133. // and all columns will have the same width like the first row.
  11134. // We set below just width=1 of the tables.
  11135. $(htbl).width(1);
  11136. // resizing stuff
  11137. $(grid.fhDiv).append(htbl)
  11138. .scroll(function () {
  11139. // the fhDiv can be scrolled because of tab keyboard navigation
  11140. // we prevent horizontal scrolling of fhDiv
  11141. this.scrollLeft = 0;
  11142. });
  11143. if (p.footerrow) {
  11144. var hbd = $(".ui-jqgrid-bdiv", p.gView).height();
  11145. grid.fsDiv = $("<div style='position:absolute;" + (p.direction === "rtl" ? "right:0;" : "left:0;") + "top:" + (parseInt(top, 10) + parseInt(hth, 10) + parseInt(hbd, 10) + 1) + "px;' class='frozen-sdiv ui-jqgrid-sdiv'></div>");
  11146. $(p.gView).append(grid.fsDiv);
  11147. var ftbl = $(".ui-jqgrid-ftable", p.gView).clone(true);
  11148. $("tr", ftbl).each(function () {
  11149. $("td:gt(" + maxfrozen + ")", this).remove();
  11150. });
  11151. $(ftbl).width(1);
  11152. $(grid.fsDiv).append(ftbl);
  11153. }
  11154. // data stuff
  11155. //TODO support for setRowData
  11156. $(p.gView).append(grid.fbDiv);
  11157. $(grid.bDiv).scroll(function () {
  11158. $(grid.fbDiv).scrollTop($(this).scrollTop());
  11159. });
  11160. $(grid.fbDiv).on("mousewheel.setFrozenColumns DOMMouseScroll.setFrozenColumns", function (e) {
  11161. grid.bDiv.scrollTop += $.isFunction(o.mouseWheel) ?
  11162. o.mouseWheel.call($t, e) :
  11163. e.type === "mousewheel" ?
  11164. -e.originalEvent.wheelDelta / 10 :
  11165. e.originalEvent.detail * 6;
  11166. });
  11167. if (p.hoverrows === true) {
  11168. $(p.idSel).off("mouseover.jqGrid mouseout.jqGrid");
  11169. }
  11170. var safeHeightSet = function ($elem, newHeight) {
  11171. var height = $elem.height();
  11172. if (Math.abs(height - newHeight) >= 1 && newHeight > 0) {
  11173. $elem.height(newHeight);
  11174. height = $elem.height();
  11175. if (Math.abs(newHeight - height) >= 1) {
  11176. $elem.height(newHeight + Math.round((newHeight - height)));
  11177. }
  11178. }
  11179. },
  11180. safeWidthSet = function ($elem, newWidth) {
  11181. var width = $elem.width();
  11182. if (Math.abs(width - newWidth) >= 1) {
  11183. $elem.width(newWidth);
  11184. width = $elem.width();
  11185. if (Math.abs(newWidth - width) >= 1) {
  11186. $elem.width(newWidth + Math.round((newWidth - width)));
  11187. }
  11188. }
  11189. },
  11190. fixDiv = function ($hDiv, hDivBase, iRowStart, iRowEnd) {
  11191. var iRow, n, $frozenRows, $rows, $row, $frozenRow, posFrozenTop, height, newHeightFrozen, td,
  11192. posTop = $(hDivBase).position().top, frozenTableTop, tableTop, cells;
  11193. if ($hDiv != null && $hDiv.length > 0) {
  11194. $hDiv[0].scrollTop = hDivBase.scrollTop;
  11195. $hDiv.css(p.direction === "rtl" ?
  11196. { top: posTop, right: 0 } :
  11197. { top: posTop, left: 0 }
  11198. );
  11199. // first try with thead for the hdiv
  11200. $frozenRows = $hDiv.children("table").children("thead").children("tr");
  11201. $rows = $(hDivBase).children("div").children("table").children("thead").children("tr");
  11202. if ($rows.length === 0 && $hDiv.children("table").length > 0) {
  11203. // then use tbody for bdiv
  11204. $frozenRows = $($hDiv.children("table")[0].rows);
  11205. $rows = $($(hDivBase).children("div").children("table")[0].rows);
  11206. }
  11207. n = Math.min($frozenRows.length, $rows.length);
  11208. frozenTableTop = n > 0 ? $($frozenRows[0]).position().top : 0;
  11209. tableTop = n > 0 ? $($rows[0]).position().top : 0; // typically 0
  11210. if (iRowStart >= 0) { // negative iRowStart means no changing of the height of individual rows
  11211. if (iRowEnd >= 0) { // negative iRowEnd means all rows
  11212. n = Math.min(iRowEnd + 1, n);
  11213. }
  11214. for (iRow = iRowStart; iRow < n; iRow++) {
  11215. // but after that one have to verify all scenarios
  11216. $row = $($rows[iRow]);
  11217. if ($row.css("display") !== "none" && $row.is(":visible")) {
  11218. posTop = $row.position().top;
  11219. $frozenRow = $($frozenRows[iRow]);
  11220. posFrozenTop = $frozenRow.position().top;
  11221. height = $row.height();
  11222. if (p.groupHeader != null && p.groupHeader.useColSpanStyle) {
  11223. cells = $row[0].cells;
  11224. for (i = 0; i < cells.length; i++) { // maxfrozen
  11225. td = cells[i];
  11226. if (td != null && td.nodeName.toUpperCase() === "TH") {
  11227. height = Math.max(height, $(td).height());
  11228. }
  11229. }
  11230. }
  11231. newHeightFrozen = height + (posTop - tableTop) + (frozenTableTop - posFrozenTop);
  11232. safeHeightSet($frozenRow, newHeightFrozen);
  11233. }
  11234. }
  11235. }
  11236. safeHeightSet($hDiv, hDivBase.clientHeight);
  11237. }
  11238. },
  11239. /** @const */
  11240. resizeAll = {
  11241. resizeDiv: true,
  11242. resizedRows: {
  11243. iRowStart: 0,
  11244. iRowEnd: -1 // -1 means "till the end"
  11245. }
  11246. },
  11247. /** @const */
  11248. fullResize = {
  11249. header: resizeAll,
  11250. resizeFooter: true,
  11251. body: resizeAll
  11252. };
  11253. $self.on("jqGridAfterGridComplete.setFrozenColumns", function () {
  11254. $(p.idSel + "_frozen").remove();
  11255. $(grid.fbDiv).height(grid.hDiv.clientHeight);
  11256. // clone with data and events !!!
  11257. var $frozenBTable = $(this).clone(true),
  11258. frozenRows = $frozenBTable[0].rows,
  11259. rows = $self[0].rows;
  11260. $(frozenRows).filter("tr[role=row]").each(function () {
  11261. $(this.cells).filter("td[role=gridcell]:gt(" + maxfrozen + ")").remove();
  11262. /*if (this.id) {
  11263. $(this).attr("id", this.id + "_frozen");
  11264. }*/
  11265. });
  11266. grid.fbRows = frozenRows;
  11267. $frozenBTable.width(1).attr("id", p.id + "_frozen");
  11268. $frozenBTable.appendTo(grid.fbDiv);
  11269. if (p.hoverrows === true) {
  11270. var hoverRows = function (tr, method, additionalRows) {
  11271. $(tr)[method](hoverClasses);
  11272. $(additionalRows[tr.rowIndex])[method](hoverClasses);
  11273. };
  11274. $(frozenRows).filter(".jqgrow").hover(
  11275. function () {
  11276. hoverRows(this, "addClass", rows);
  11277. },
  11278. function () {
  11279. hoverRows(this, "removeClass", rows);
  11280. }
  11281. );
  11282. $(rows).filter(".jqgrow").hover(
  11283. function () {
  11284. hoverRows(this, "addClass", frozenRows);
  11285. },
  11286. function () {
  11287. hoverRows(this, "removeClass", frozenRows);
  11288. }
  11289. );
  11290. }
  11291. fixDiv(grid.fhDiv, grid.hDiv, 0, -1);
  11292. fixDiv(grid.fbDiv, grid.bDiv, 0, -1);
  11293. if (grid.sDiv) { fixDiv(grid.fsDiv, grid.sDiv, 0, -1); }
  11294. });
  11295. var myResize = function (resizeOptions) {
  11296. $(grid.fbDiv).scrollTop($(grid.bDiv).scrollTop());
  11297. // TODO: the width of all column headers can be changed
  11298. // so one should recalculate frozenWidth in other way.
  11299. if (resizeOptions.header.resizeDiv) {
  11300. fixDiv(grid.fhDiv, grid.hDiv, resizeOptions.header.resizedRows.iRowStart, resizeOptions.header.resizedRows.iRowEnd);
  11301. }
  11302. if (resizeOptions.body.resizeDiv) {
  11303. fixDiv(grid.fbDiv, grid.bDiv, resizeOptions.body.resizedRows.iRowStart, resizeOptions.body.resizedRows.iRowEnd);
  11304. }
  11305. if (resizeOptions.resizeFooter && grid.sDiv && resizeOptions.resizeFooter) {
  11306. fixDiv(grid.fsDiv, grid.sDiv, 0, -1);
  11307. }
  11308. var frozenWidth = grid.fhDiv[0].clientWidth;
  11309. if (resizeOptions.header.resizeDiv && grid.fhDiv != null && grid.fhDiv.length >= 1) {
  11310. safeHeightSet($(grid.fhDiv), grid.hDiv.clientHeight);
  11311. }
  11312. if (resizeOptions.body.resizeDiv && grid.fbDiv != null && grid.fbDiv.length > 0) {
  11313. safeWidthSet($(grid.fbDiv), frozenWidth);
  11314. }
  11315. if (resizeOptions.resizeFooter && grid.fsDiv != null && grid.fsDiv.length >= 0) {
  11316. safeWidthSet($(grid.fsDiv), frozenWidth);
  11317. }
  11318. };
  11319. $(p.gBox).on("resizestop.setFrozenColumns", function () {
  11320. setTimeout(function () {
  11321. myResize(fullResize);
  11322. }, 50);
  11323. });
  11324. $self.on("jqGridInlineEditRow.setFrozenColumns jqGridInlineAfterRestoreRow.setFrozenColumns jqGridInlineAfterSaveRow.setFrozenColumns jqGridAfterEditCell.setFrozenColumns jqGridAfterRestoreCell.setFrozenColumns jqGridAfterSaveCell.setFrozenColumns jqGridResizeStop.setFrozenColumns", function (e, rowid) {
  11325. // TODO: probably one should handle additional events like afterSetRow
  11326. // and remove jqGridInlineAfterSaveRow and jqGridInlineAfterRestoreRow
  11327. var iRow = $self.jqGrid("getInd", rowid);
  11328. myResize({
  11329. header: {
  11330. resizeDiv: false, // don't recalculate the position and the height of hDiv
  11331. resizedRows: {
  11332. iRowStart: -1, // -1 means don't recalculate heights or rows
  11333. iRowEnd: -1
  11334. }
  11335. },
  11336. resizeFooter: true, // recalculate the position and the height of sDiv
  11337. body: {
  11338. resizeDiv: true, // recalculate the position and the height of bDiv
  11339. resizedRows: {
  11340. // recalculate the height of only one row inside of bDiv
  11341. iRowStart: iRow,
  11342. iRowEnd: iRow
  11343. }
  11344. }
  11345. });
  11346. });
  11347. $self.on("jqGridResizeStop.setFrozenColumns", function () {
  11348. myResize(fullResize);
  11349. });
  11350. $self.on("jqGridResetFrozenHeights.setFrozenColumns", function (e, o) {
  11351. myResize(o || fullResize);
  11352. });
  11353. if (!grid.hDiv.loading) {
  11354. setTimeout(function () {
  11355. $self.triggerHandler("jqGridAfterGridComplete");
  11356. }, 0);
  11357. }
  11358. p.frozenColumns = true;
  11359. }
  11360. });
  11361. },
  11362. destroyFrozenColumns: function () {
  11363. return this.each(function () {
  11364. var $t = this, $self = $($t), grid = $t.grid, p = $t.p, tid = jqID(p.id);
  11365. if (!grid) { return; }
  11366. if (p.frozenColumns === true) {
  11367. $(grid.fhDiv).remove();
  11368. $(grid.fbDiv).off(".setFrozenColumns");
  11369. $(grid.fbDiv).remove();
  11370. grid.fhDiv = null;
  11371. grid.fbDiv = null;
  11372. grid.fbRows = null;
  11373. if (p.footerrow) {
  11374. $(grid.fsDiv).remove();
  11375. grid.fsDiv = null;
  11376. }
  11377. $self.off(".setFrozenColumns");
  11378. if (p.hoverrows === true) {
  11379. var ptr, hoverClasses = getGuiStyles.call($t, "states.hover");
  11380. $self.on("mouseover.jqGrid", function (e) {
  11381. ptr = $(e.target).closest("tr.jqgrow");
  11382. if ($(ptr).attr("class") !== "ui-subgrid") {
  11383. $(ptr).addClass(hoverClasses);
  11384. }
  11385. }).on("mouseout.jqGrid", function (e) {
  11386. ptr = $(e.target).closest("tr.jqgrow");
  11387. $(ptr).removeClass(hoverClasses);
  11388. });
  11389. }
  11390. p.frozenColumns = false;
  11391. if (p.sortable) {
  11392. var $colHeaderRow = $(grid.hDiv).find(".ui-jqgrid-htable .ui-jqgrid-labels");
  11393. $colHeaderRow.sortable("destroy");
  11394. $self.jqGrid("setGridParam", {
  11395. sortable: {
  11396. options: {
  11397. items: ">th:not(:has(#jqgh_" + tid + "_cb" + ",#jqgh_" + tid + "_rn" + ",#jqgh_" + tid + "_subgrid),:hidden)"
  11398. }
  11399. }
  11400. });
  11401. $self.jqGrid("sortableColumns", $colHeaderRow);
  11402. }
  11403. }
  11404. });
  11405. }
  11406. });
  11407. // end module grid.custom
  11408. /**
  11409. * jqFilter jQuery jqGrid filter addon.
  11410. * Copyright (c) 2011-2014, Tony Tomov, tony@trirand.com
  11411. * Copyright (c) 2014-2018, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  11412. * Dual licensed under the MIT and GPL licenses
  11413. * http://www.opensource.org/licenses/mit-license.php
  11414. * http://www.gnu.org/licenses/gpl-2.0.html
  11415. *
  11416. * The work is inspired from this Stefan Pirvu
  11417. * http://www.codeproject.com/KB/scripting/json-filtering.aspx
  11418. *
  11419. * The filter uses JSON entities to hold filter rules and groups. Here is an example of a filter:
  11420. { "groupOp": "AND",
  11421. "groups" : [
  11422. { "groupOp": "OR",
  11423. "rules": [
  11424. { "field": "name", "op": "eq", "data": "England" },
  11425. { "field": "id", "op": "le", "data": "5"}
  11426. ]
  11427. }
  11428. ],
  11429. "rules": [
  11430. { "field": "name", "op": "eq", "data": "Romania" },
  11431. { "field": "id", "op": "le", "data": "1"}
  11432. ]
  11433. }
  11434. */
  11435. // begin module grid.filter
  11436. $.fn.jqFilter = function (arg) {
  11437. if (typeof arg === "string") {
  11438. var fn = $.fn.jqFilter[arg];
  11439. if (!fn) {
  11440. throw ("jqFilter - No such method: " + arg);
  11441. }
  11442. var args = $.makeArray(arguments).slice(1);
  11443. return fn.apply(this, args);
  11444. }
  11445. var p = $.extend(true, {
  11446. filter: null,
  11447. columns: [],
  11448. onChange: null,
  11449. afterRedraw: null,
  11450. error: false,
  11451. errmsg: "",
  11452. errorcheck: true,
  11453. showQuery: true,
  11454. sopt: null,
  11455. ops: [],
  11456. operands: null,
  11457. numopts: ["eq", "ne", "lt", "le", "gt", "ge", "nu", "nn", "in", "ni"],
  11458. stropts: ["eq", "ne", "bw", "bn", "ew", "en", "cn", "nc", "nu", "nn", "in", "ni"],
  11459. strarr: ["text", "string", "blob"],
  11460. groupOps: [{ op: "AND", text: "AND" }, { op: "OR", text: "OR" }],
  11461. groupButton: true,
  11462. ruleButtons: true,
  11463. direction: "ltr"
  11464. }, jgrid.filter, arg || {});
  11465. return this.each(function () {
  11466. if (this.filter) { return; }
  11467. this.p = p;
  11468. // setup filter in case if they is not defined
  11469. if (p.filter === null || p.filter === undefined) {
  11470. p.filter = {
  11471. groupOp: p.groupOps[0].op,
  11472. rules: [],
  11473. groups: []
  11474. };
  11475. }
  11476. var iColumn, len = p.columns.length, cl, isIE = /msie/i.test(navigator.userAgent) && !window.opera,
  11477. isFunction = $.isFunction,
  11478. fatalErrorFunction = jgrid.defaults != null && isFunction(jgrid.defaults.fatalError) ? jgrid.defaults.fatalError : alert,
  11479. getGrid = function () {
  11480. return $("#" + jgrid.jqID(p.id))[0] || null;
  11481. },
  11482. getGuiStyles = function (path, jqClasses) {
  11483. return $(getGrid()).jqGrid("getGuiStyles", path, jqClasses || "");
  11484. },
  11485. getRes = function (property) {
  11486. return $(getGrid()).jqGrid("getGridRes", "search." + property);
  11487. },
  11488. getCmInfo = function (cmName) {
  11489. // the function convert column name or advanced property name to
  11490. // object with properties { cm: , iCol: }
  11491. var $t = getGrid(), iCol = $t.p.iColByName[cmName]; //iPropByName
  11492. if (iCol !== undefined) {
  11493. return { cm: $t.p.colModel[iCol], iCol: iCol };
  11494. }
  11495. iCol = $t.p.iPropByName[cmName];
  11496. if (iCol !== undefined) {
  11497. return { cm: $t.p.additionalProperties[iCol], iCol: iCol, isAddProp: true };
  11498. }
  11499. return { cm: null, iCol: -1 };
  11500. },
  11501. errorClass = getGuiStyles("states.error"),
  11502. dialogContentClass = getGuiStyles("dialog.content");
  11503. // translating the options
  11504. p.initFilter = $.extend(true, {}, p.filter);
  11505. // set default values for the columns if they are not set
  11506. if (!len) { return; }
  11507. for (iColumn = 0; iColumn < len; iColumn++) {
  11508. cl = p.columns[iColumn];
  11509. if (cl.stype) {
  11510. // grid compatibility
  11511. cl.inputtype = cl.stype;
  11512. } else if (!cl.inputtype) {
  11513. cl.inputtype = "text";
  11514. }
  11515. if (cl.sorttype) {
  11516. // grid compatibility
  11517. cl.searchtype = cl.sorttype;
  11518. } else if (!cl.searchtype) {
  11519. cl.searchtype = "string";
  11520. }
  11521. if (cl.hidden === undefined) {
  11522. // jqGrid compatibility
  11523. cl.hidden = false;
  11524. }
  11525. if (!cl.label) {
  11526. cl.label = cl.name;
  11527. }
  11528. cl.cmName = cl.name;
  11529. if (cl.index) {
  11530. cl.name = cl.index;
  11531. }
  11532. if (!cl.hasOwnProperty("searchoptions")) {
  11533. cl.searchoptions = {};
  11534. }
  11535. if (!cl.hasOwnProperty("searchrules")) {
  11536. cl.searchrules = {};
  11537. }
  11538. }
  11539. if (p.showQuery) {
  11540. $(this).append("<table class='queryresult " + dialogContentClass +
  11541. "' style='display:block;max-width:440px;border:0px none;' dir='" + p.direction + "'><tbody><tr><td class='query'></td></tr></tbody></table>");
  11542. }
  11543. /*
  11544. *Perform checking.
  11545. *
  11546. */
  11547. var checkData = function (val, colModelItem) {
  11548. var ret = [true, ""], $t = getGrid();
  11549. if (isFunction(colModelItem.searchrules)) {
  11550. ret = colModelItem.searchrules.call($t, val, colModelItem);
  11551. } else if (jgrid && jgrid.checkValues) {
  11552. try {
  11553. ret = jgrid.checkValues.call($t, val, -1, colModelItem.searchrules, colModelItem.label);
  11554. } catch (ignore) { }
  11555. }
  11556. if (ret && ret.length && ret[0] === false) {
  11557. p.error = !ret[0];
  11558. p.errmsg = ret[1];
  11559. }
  11560. };
  11561. /* moving to common
  11562. randId = function() {
  11563. return Math.floor(Math.random()*10000).toString();
  11564. };
  11565. */
  11566. this.onchange = function () {
  11567. // clear any error
  11568. p.error = false;
  11569. p.errmsg = "";
  11570. return isFunction(p.onChange) ? p.onChange.call(getGrid(), p, this) : false;
  11571. };
  11572. /*
  11573. * Redraw the filter every time when new field is added/deleted
  11574. * and field is changed
  11575. */
  11576. this.reDraw = function () {
  11577. $("table.group:first", this).remove();
  11578. var t = this.createTableForGroup(p.filter, null);
  11579. $(this).append(t);
  11580. if (isFunction(p.afterRedraw)) {
  11581. p.afterRedraw.call(getGrid(), p, this);
  11582. }
  11583. };
  11584. /**
  11585. * Creates a grouping data for the filter
  11586. * @param group - object
  11587. * @param parentgroup - object
  11588. */
  11589. this.createTableForGroup = function (group, parentgroup) {
  11590. var that = this, i;
  11591. // this table will hold all the group (tables) and rules (rows)
  11592. var table = $("<table class='" + getGuiStyles("searchDialog.operationGroup", "group") +
  11593. "' style='border:0px none;'><tbody></tbody></table>"), align = "left";
  11594. // create error message row
  11595. if (p.direction === "rtl") {
  11596. align = "right";
  11597. table.attr("dir", "rtl");
  11598. }
  11599. if (parentgroup === null) {
  11600. table.append("<tr class='error' style='display:none;'><th colspan='5' class='" + errorClass + "' align='" + align + "'></th></tr>");
  11601. }
  11602. var tr = $("<tr></tr>");
  11603. table.append(tr);
  11604. // this header will hold the group operator type and group action buttons for
  11605. // creating subgroup "+ {}", creating rule "+" or deleting the group "-"
  11606. var th = $("<th colspan='5' align='" + align + "'></th>");
  11607. tr.append(th);
  11608. if (p.ruleButtons === true) {
  11609. // dropdown for: choosing group operator type
  11610. var groupOpSelect = $("<select class='" + getGuiStyles("searchDialog.operationSelect", "opsel") + "'></select>");
  11611. th.append(groupOpSelect);
  11612. // populate dropdown with all posible group operators: or, and
  11613. var str = "", selected;
  11614. for (i = 0; i < p.groupOps.length; i++) {
  11615. selected = group.groupOp === that.p.groupOps[i].op ? " selected='selected'" : "";
  11616. str += "<option value='" + that.p.groupOps[i].op + "'" + selected + ">" + that.p.groupOps[i].text + "</option>";
  11617. }
  11618. groupOpSelect.append(str)
  11619. .on("change", function () {
  11620. group.groupOp = $(groupOpSelect).val();
  11621. that.onchange(); // signals that the filter has changed
  11622. });
  11623. }
  11624. // button for adding a new subgroup
  11625. var inputAddSubgroup = "<span></span>";
  11626. if (p.groupButton) {
  11627. inputAddSubgroup = $("<input type='button' value='+ {}' title='" + getRes("addGroupTitle") + "' class='" +
  11628. getGuiStyles("searchDialog.addGroupButton", "add-group") + "'/>");
  11629. inputAddSubgroup.on("click", function () {
  11630. if (group.groups === undefined) {
  11631. group.groups = [];
  11632. }
  11633. group.groups.push({
  11634. groupOp: p.groupOps[0].op,
  11635. rules: [],
  11636. groups: []
  11637. }); // adding a new group
  11638. that.reDraw(); // the html has changed, force reDraw
  11639. that.onchange(); // signals that the filter has changed
  11640. return false;
  11641. });
  11642. }
  11643. th.append(inputAddSubgroup);
  11644. if (p.ruleButtons === true) {
  11645. // button for adding a new rule
  11646. var inputAddRule = $("<input type='button' value='+' title='" + getRes("addRuleTitle") + "' class='" +
  11647. getGuiStyles("searchDialog.addRuleButton", "add-rule ui-add") + "'/>"), cm;
  11648. inputAddRule.on("click", function () {
  11649. var searchable, hidden, ignoreHiding;
  11650. //if(!group) { group = {};}
  11651. if (group.rules === undefined) {
  11652. group.rules = [];
  11653. }
  11654. for (i = 0; i < that.p.columns.length; i++) {
  11655. // but show only serchable and serchhidden = true fields
  11656. searchable = (that.p.columns[i].search === undefined) ? true : that.p.columns[i].search;
  11657. hidden = (that.p.columns[i].hidden === true);
  11658. ignoreHiding = (that.p.columns[i].searchoptions.searchhidden === true);
  11659. if ((ignoreHiding && searchable) || (searchable && !hidden)) {
  11660. cm = that.p.columns[i];
  11661. break;
  11662. }
  11663. }
  11664. var opr;
  11665. if (cm.searchoptions.sopt) {
  11666. opr = cm.searchoptions.sopt;
  11667. } else if (that.p.sopt) {
  11668. opr = that.p.sopt;
  11669. } else if ($.inArray(cm.searchtype, that.p.strarr) !== -1) {
  11670. opr = that.p.stropts;
  11671. } else {
  11672. opr = that.p.numopts;
  11673. }
  11674. group.rules.push({
  11675. field: cm.name,
  11676. op: opr[0],
  11677. data: ""
  11678. }); // adding a new rule
  11679. that.reDraw(); // the html has changed, force reDraw
  11680. // for the moment no change have been made to the rule, so
  11681. // this will not trigger onchange event
  11682. return false;
  11683. });
  11684. th.append(inputAddRule);
  11685. }
  11686. // button for delete the group
  11687. if (parentgroup !== null) { // ignore the first group
  11688. var inputDeleteGroup = $("<input type='button' value='-' title='" + getRes("deleteGroupTitle") + "' class='" +
  11689. getGuiStyles("searchDialog.deleteGroupButton", "delete-group") + "'/>");
  11690. th.append(inputDeleteGroup);
  11691. inputDeleteGroup.on("click", function () {
  11692. // remove group from parent
  11693. for (i = 0; i < parentgroup.groups.length; i++) {
  11694. if (parentgroup.groups[i] === group) {
  11695. parentgroup.groups.splice(i, 1);
  11696. break;
  11697. }
  11698. }
  11699. that.reDraw(); // the html has changed, force reDraw
  11700. that.onchange(); // signals that the filter has changed
  11701. return false;
  11702. });
  11703. }
  11704. // append subgroup rows
  11705. if (group.groups !== undefined) {
  11706. var trHolderForSubgroup, tdFirstHolderForSubgroup, tdMainHolderForSubgroup;
  11707. for (i = 0; i < group.groups.length; i++) {
  11708. trHolderForSubgroup = $("<tr></tr>");
  11709. table.append(trHolderForSubgroup);
  11710. tdFirstHolderForSubgroup = $("<td class='first'></td>");
  11711. trHolderForSubgroup.append(tdFirstHolderForSubgroup);
  11712. tdMainHolderForSubgroup = $("<td colspan='4'></td>");
  11713. tdMainHolderForSubgroup.append(this.createTableForGroup(group.groups[i], group));
  11714. trHolderForSubgroup.append(tdMainHolderForSubgroup);
  11715. }
  11716. }
  11717. if (group.groupOp === undefined) {
  11718. group.groupOp = that.p.groupOps[0].op;
  11719. }
  11720. // append rules rows
  11721. if (group.rules !== undefined) {
  11722. for (i = 0; i < group.rules.length; i++) {
  11723. table.append(
  11724. this.createTableRowForRule(group.rules[i], group)
  11725. );
  11726. }
  11727. }
  11728. return table;
  11729. };
  11730. /*
  11731. * Create the rule data for the filter
  11732. */
  11733. this.createTableRowForRule = function (rule, group) {
  11734. // save current entity in a variable so that it could
  11735. // be referenced in anonimous method calls
  11736. var that = this, $t = getGrid(), tr = $("<tr></tr>"),
  11737. i, op, cm, str = "", selected;
  11738. tr.append("<td class='first'></td>");
  11739. // create field container
  11740. var ruleFieldTd = $("<td class='columns'></td>");
  11741. tr.append(ruleFieldTd);
  11742. // dropdown for: choosing field
  11743. var ruleFieldSelect = $("<select class='" + getGuiStyles("searchDialog.label", "selectLabel") +
  11744. "'></select>"), ina, aoprs = [];
  11745. ruleFieldTd.append(ruleFieldSelect);
  11746. ruleFieldSelect.on("change", function () {
  11747. rule.field = $(ruleFieldSelect).val();
  11748. var trpar = $(this).parents("tr:first"), columns, k; // define LOCAL variables
  11749. for (k = 0; k < that.p.columns.length; k++) {
  11750. if (that.p.columns[k].name === rule.field) {
  11751. columns = that.p.columns[k];
  11752. break;
  11753. }
  11754. }
  11755. if (!columns) { return; }
  11756. var editoptions = $.extend({}, columns.editoptions || {});
  11757. delete editoptions.readonly;
  11758. delete editoptions.disabled;
  11759. var searchoptions = $.extend(
  11760. {},
  11761. editoptions || {},
  11762. columns.searchoptions || {},
  11763. getCmInfo(columns.cmName),
  11764. { id: jgrid.randId(), name: columns.name, mode: "search" }
  11765. );
  11766. searchoptions.column = columns; // add reference to that.p.columns[k];
  11767. if (isIE && columns.inputtype === "text") {
  11768. if (!searchoptions.size) {
  11769. searchoptions.size = 10;
  11770. }
  11771. }
  11772. var elm = jgrid.createEl.call($t, columns.inputtype,
  11773. $.extend({}, searchoptions, searchoptions.attr || {}),
  11774. "", true, that.p.ajaxSelectOptions || {}, true);
  11775. $(elm).addClass(getGuiStyles("searchDialog.elem", "input-elm"));
  11776. //that.createElement(rule, "");
  11777. if (searchoptions.sopt) {
  11778. op = searchoptions.sopt;
  11779. } else if (that.p.sopt) {
  11780. op = that.p.sopt;
  11781. } else if ($.inArray(columns.searchtype, that.p.strarr) !== -1) {
  11782. op = that.p.stropts;
  11783. } else {
  11784. op = that.p.numopts;
  11785. }
  11786. // operators
  11787. var s = "", so = 0, odataItem1, itemOper1, itemText;
  11788. aoprs = [];
  11789. $.each(that.p.ops, function () { aoprs.push(this.oper); });
  11790. // append aoprs array with custom operations defined in customSortOperations parameter jqGrid
  11791. if (that.p.cops) {
  11792. $.each(that.p.cops, function (propertyName) { aoprs.push(propertyName); });
  11793. }
  11794. for (k = 0; k < op.length; k++) {
  11795. itemOper1 = op[k];
  11796. ina = $.inArray(op[k], aoprs);
  11797. if (ina !== -1) {
  11798. odataItem1 = that.p.ops[ina];
  11799. itemText = odataItem1 !== undefined ? odataItem1.text : that.p.cops[itemOper1].text;
  11800. if (so === 0) {
  11801. // the first select item will be automatically selected in single-select
  11802. rule.op = itemOper1;
  11803. }
  11804. s += "<option value='" + itemOper1 + "'>" + itemText + "</option>";
  11805. so++;
  11806. }
  11807. }
  11808. $(".selectopts", trpar).empty().append(s);
  11809. $(".selectopts", trpar)[0].selectedIndex = 0;
  11810. if (jgrid.msie && jgrid.msiever() < 9) {
  11811. var sw = parseInt($("select.selectopts", trpar)[0].offsetWidth, 10) + 1;
  11812. $(".selectopts", trpar).width(sw);
  11813. $(".selectopts", trpar).css("width", "auto");
  11814. }
  11815. // data
  11816. $(".data", trpar).empty().append(elm);
  11817. if (columns.createColumnIndex && searchoptions.generateDatalist) {
  11818. var dataListId = "dl_" + elm.id,
  11819. $datalist = $($t).jqGrid("generateDatalistFromColumnIndex", columns.name);
  11820. if ($datalist != null && $datalist.length > 0) {
  11821. $(elm).attr("list", dataListId);
  11822. $(".data", trpar).append($datalist.attr("id", dataListId));
  11823. }
  11824. }
  11825. jgrid.bindEv.call($t, elm, searchoptions);
  11826. $(".input-elm", trpar).on("change", searchoptions, function (e) {
  11827. var elem = e.target, column = e.data.column;
  11828. rule.data = column && column.inputtype === "custom" && isFunction(column.searchoptions.custom_value) ?
  11829. column.searchoptions.custom_value.call($t, $(this).find(".customelement").first(), "get") :
  11830. elem.value;
  11831. if ($(elem).is("input[type=checkbox]") && !$(elem).is(":checked")) {
  11832. // value of checkbox contains checked value
  11833. rule.data = $(elem).data("offval");
  11834. }
  11835. that.onchange(); // signals that the filter has changed
  11836. });
  11837. setTimeout(function () { //IE, Opera, Chrome
  11838. rule.data = $(elm).val();
  11839. that.onchange(); // signals that the filter has changed
  11840. }, 0);
  11841. });
  11842. // populate drop down with user provided column definitions
  11843. var j = 0, searchable, hidden, ignoreHiding;
  11844. for (i = 0; i < that.p.columns.length; i++) {
  11845. // but show only serchable and serchhidden = true fields
  11846. searchable = (that.p.columns[i].search === undefined) ? true : that.p.columns[i].search;
  11847. hidden = (that.p.columns[i].hidden === true);
  11848. ignoreHiding = (that.p.columns[i].searchoptions.searchhidden === true);
  11849. if ((ignoreHiding && searchable) || (searchable && !hidden)) {
  11850. selected = "";
  11851. if (rule.field === that.p.columns[i].name) {
  11852. selected = " selected='selected'";
  11853. j = i;
  11854. }
  11855. str += "<option value='" + that.p.columns[i].name + "'" + selected + ">" + that.p.columns[i].label + "</option>";
  11856. }
  11857. }
  11858. ruleFieldSelect.append(str);
  11859. // create operator container
  11860. var ruleOperatorTd = $("<td class='operators'></td>");
  11861. tr.append(ruleOperatorTd);
  11862. cm = p.columns[j];
  11863. // create it here so it can be referentiated in the onchange event
  11864. //var RD = that.createElement(rule, rule.data);
  11865. if (isIE && cm.inputtype === "text") {
  11866. if (!cm.searchoptions.size) {
  11867. cm.searchoptions.size = 10;
  11868. }
  11869. }
  11870. var editoptions = $.extend({}, cm.editoptions || {});
  11871. delete editoptions.readonly;
  11872. delete editoptions.disabled;
  11873. var searchoptions = $.extend(
  11874. {},
  11875. editoptions,
  11876. cm.searchoptions || {},
  11877. getCmInfo(cm.cmName),
  11878. { id: jgrid.randId(), name: cm.name, mode: "search" });
  11879. searchoptions.column = cm;
  11880. var ruleDataInput = jgrid.createEl.call($t, cm.inputtype,
  11881. $.extend({}, searchoptions, searchoptions.attr || {}),
  11882. rule.data, true, that.p.ajaxSelectOptions || {}, true);
  11883. if (rule.op === "nu" || rule.op === "nn" || $.inArray(rule.op, $t.p.customUnaryOperations) >= 0) {
  11884. $(ruleDataInput).attr("readonly", "true");
  11885. $(ruleDataInput).attr("disabled", "true");
  11886. } //retain the state of disabled text fields in case of null ops
  11887. // dropdown for: choosing operator
  11888. var ruleOperatorSelect = $("<select class='" + getGuiStyles("searchDialog.operator", "selectopts") + "'></select>");
  11889. ruleOperatorTd.append(ruleOperatorSelect);
  11890. ruleOperatorSelect.on("change", function () {
  11891. rule.op = $(ruleOperatorSelect).val();
  11892. var trpar = $(this).parents("tr:first"),
  11893. rd = $(".input-elm", trpar)[0];
  11894. if (rule.op === "nu" || rule.op === "nn" || $.inArray(rule.op, $t.p.customUnaryOperations) >= 0) { // disable for operator "is null" and "is not null"
  11895. rule.data = "";
  11896. if (rd.tagName.toUpperCase() !== "SELECT") { rd.value = ""; }
  11897. rd.setAttribute("readonly", "true");
  11898. rd.setAttribute("disabled", "true");
  11899. } else {
  11900. if (rd.tagName.toUpperCase() === "SELECT") { rule.data = rd.value; }
  11901. rd.removeAttribute("readonly");
  11902. rd.removeAttribute("disabled");
  11903. }
  11904. that.onchange(); // signals that the filter has changed
  11905. });
  11906. // populate drop down with all available operators
  11907. if (cm.searchoptions.sopt) {
  11908. op = cm.searchoptions.sopt;
  11909. } else if (that.p.sopt) {
  11910. op = that.p.sopt;
  11911. } else if ($.inArray(cm.searchtype, that.p.strarr) !== -1) {
  11912. op = that.p.stropts;
  11913. } else {
  11914. op = that.p.numopts;
  11915. }
  11916. str = "";
  11917. var odataItem, itemOper;
  11918. $.each(that.p.ops, function () { aoprs.push(this.oper); });
  11919. // append aoprs array with custom operations defined in customSortOperations parameter jqGrid
  11920. if (that.p.cops) {
  11921. $.each(that.p.cops, function (propertyName) { aoprs.push(propertyName); });
  11922. }
  11923. for (i = 0; i < op.length; i++) {
  11924. itemOper = op[i];
  11925. ina = $.inArray(op[i], aoprs);
  11926. if (ina !== -1) {
  11927. odataItem = that.p.ops[ina];
  11928. selected = rule.op === itemOper ? " selected='selected'" : "";
  11929. str += "<option value='" + itemOper + "'" + selected + ">" +
  11930. (odataItem !== undefined ? odataItem.text : that.p.cops[itemOper].text) +
  11931. "</option>";
  11932. }
  11933. }
  11934. ruleOperatorSelect.append(str);
  11935. // create data container
  11936. var ruleDataTd = $("<td class='data'></td>");
  11937. tr.append(ruleDataTd);
  11938. // textbox for: data
  11939. // is created previously
  11940. //ruleDataInput.setAttribute("type", "text");
  11941. ruleDataTd.append(ruleDataInput);
  11942. if (cm.createColumnIndex && cm.searchoptions.generateDatalist) {
  11943. var dataListId = "dl_" + ruleDataInput.id,
  11944. $datalist = $($t).jqGrid("generateDatalistFromColumnIndex", cm.name);
  11945. if ($datalist != null && $datalist.length > 0) {
  11946. $(ruleDataInput).attr("list", dataListId);
  11947. ruleDataTd.append($datalist.attr("id", dataListId));
  11948. }
  11949. }
  11950. jgrid.bindEv.call($t, ruleDataInput, cm.searchoptions);
  11951. $(ruleDataInput).addClass(getGuiStyles("searchDialog.elem", "input-elm"))
  11952. .on("change", function () {
  11953. rule.data = cm.inputtype === "custom" ?
  11954. cm.searchoptions.custom_value.call($t, $(this).find(".customelement").first(), "get") :
  11955. $(this).val();
  11956. if ($(this).is("input[type=checkbox]") && !$(this).is(":checked")) {
  11957. // value of checkbox contains checked value
  11958. rule.data = $(this).data("offval");
  11959. }
  11960. if ($.isArray(rule.data)) {
  11961. rule.data = rule.data.join(p.inFilterSeparator || ",");
  11962. }
  11963. that.onchange(); // signals that the filter has changed
  11964. });
  11965. // create action container
  11966. var ruleDeleteTd = $("<td></td>");
  11967. tr.append(ruleDeleteTd);
  11968. // create button for: delete rule
  11969. if (p.ruleButtons === true) {
  11970. var ruleDeleteInput = $("<input type='button' value='-' title='" + getRes("deleteRuleTitle") + "' class='" +
  11971. getGuiStyles("searchDialog.deleteRuleButton", "delete-rule ui-del") + "'/>");
  11972. ruleDeleteTd.append(ruleDeleteInput);
  11973. //$(ruleDeleteInput).html("").height(20).width(30).button({icons: { primary: "ui-icon-minus", text:false}});
  11974. ruleDeleteInput.on("click", function () {
  11975. // remove rule from group
  11976. for (i = 0; i < group.rules.length; i++) {
  11977. if (group.rules[i] === rule) {
  11978. group.rules.splice(i, 1);
  11979. break;
  11980. }
  11981. }
  11982. that.reDraw(); // the html has changed, force reDraw
  11983. that.onchange(); // signals that the filter has changed
  11984. return false;
  11985. });
  11986. }
  11987. return tr;
  11988. };
  11989. this.getStringForGroup = function (group) {
  11990. var s = "(", index;
  11991. if (group.groups !== undefined) {
  11992. for (index = 0; index < group.groups.length; index++) {
  11993. if (s.length > 1) {
  11994. s += " " + group.groupOp + " ";
  11995. }
  11996. try {
  11997. s += this.getStringForGroup(group.groups[index]);
  11998. } catch (eg) {
  11999. fatalErrorFunction(eg);
  12000. }
  12001. }
  12002. }
  12003. if (group.rules !== undefined) {
  12004. try {
  12005. for (index = 0; index < group.rules.length; index++) {
  12006. if (s.length > 1) {
  12007. s += " " + group.groupOp + " ";
  12008. }
  12009. s += this.getStringForRule(group.rules[index]);
  12010. }
  12011. } catch (e) {
  12012. fatalErrorFunction(e);
  12013. }
  12014. }
  12015. s += ")";
  12016. if (s === "()") {
  12017. return ""; // ignore groups that don't have rules
  12018. }
  12019. return s;
  12020. };
  12021. this.getStringForRule = function (rule) {
  12022. var operand = "", opC = "", i, cm, ret, val = rule.data, oper, numtypes = ["int", "integer", "float", "number", "currency"]; // jqGrid
  12023. for (i = 0; i < p.ops.length; i++) {
  12024. if (p.ops[i].oper === rule.op) {
  12025. operand = p.operands.hasOwnProperty(rule.op) ? p.operands[rule.op] : "";
  12026. opC = p.ops[i].oper;
  12027. break;
  12028. }
  12029. }
  12030. if (opC === "" && p.cops != null) {
  12031. for (oper in p.cops) {
  12032. if (p.cops.hasOwnProperty(oper)) {
  12033. opC = oper;
  12034. operand = p.cops[oper].operand;
  12035. if (isFunction(p.cops[oper].buildQueryValue)) {
  12036. return p.cops[oper].buildQueryValue.call(p, { cmName: rule.field, searchValue: val, operand: operand });
  12037. }
  12038. }
  12039. }
  12040. }
  12041. for (i = 0; i < p.columns.length; i++) {
  12042. if (p.columns[i].name === rule.field) {
  12043. cm = p.columns[i];
  12044. break;
  12045. }
  12046. }
  12047. if (cm == null) {
  12048. return "";
  12049. }
  12050. if (opC === "bw" || opC === "bn") {
  12051. val = val + "%";
  12052. }
  12053. if (opC === "ew" || opC === "en") {
  12054. val = "%" + val;
  12055. }
  12056. if (opC === "cn" || opC === "nc") {
  12057. val = "%" + val + "%";
  12058. }
  12059. if (opC === "in" || opC === "ni") {
  12060. val = " (" + val + ")";
  12061. }
  12062. if (p.errorcheck) {
  12063. checkData(rule.data, cm);
  12064. }
  12065. if ($.inArray(cm.searchtype, numtypes) !== -1 || opC === "nn" || opC === "nu" || $.inArray(opC, getGrid().p.customUnaryOperations) >= 0) {
  12066. ret = rule.field + " " + operand + " " + val;
  12067. } else {
  12068. ret = rule.field + " " + operand + ' "' + val + '"';
  12069. }
  12070. return ret;
  12071. };
  12072. this.resetFilter = function () {
  12073. p.filter = $.extend(true, {}, p.initFilter);
  12074. this.reDraw();
  12075. this.onchange();
  12076. };
  12077. this.hideError = function () {
  12078. $("th." + errorClass, this).html("");
  12079. $("tr.error", this).hide();
  12080. };
  12081. this.showError = function () {
  12082. $("th." + errorClass, this).html(p.errmsg);
  12083. $("tr.error", this).show();
  12084. };
  12085. this.toUserFriendlyString = function () {
  12086. return this.getStringForGroup(p.filter);
  12087. };
  12088. this.toString = function () {
  12089. // this will obtain a string that can be used to match an item.
  12090. var that = this;
  12091. function getStringRule(rule) {
  12092. if (that.p.errorcheck) {
  12093. var i, cm;
  12094. for (i = 0; i < that.p.columns.length; i++) {
  12095. if (that.p.columns[i].name === rule.field) {
  12096. cm = that.p.columns[i];
  12097. break;
  12098. }
  12099. }
  12100. if (cm) {
  12101. checkData(rule.data, cm);
  12102. }
  12103. }
  12104. return rule.op + "(item." + rule.field + ",'" + rule.data + "')";
  12105. }
  12106. function getStringForGroup(group) {
  12107. var s = "(", index;
  12108. if (group.groups !== undefined) {
  12109. for (index = 0; index < group.groups.length; index++) {
  12110. if (s.length > 1) {
  12111. if (group.groupOp === "OR") {
  12112. s += " || ";
  12113. } else {
  12114. s += " && ";
  12115. }
  12116. }
  12117. s += getStringForGroup(group.groups[index]);
  12118. }
  12119. }
  12120. if (group.rules !== undefined) {
  12121. for (index = 0; index < group.rules.length; index++) {
  12122. if (s.length > 1) {
  12123. if (group.groupOp === "OR") {
  12124. s += " || ";
  12125. } else {
  12126. s += " && ";
  12127. }
  12128. }
  12129. s += getStringRule(group.rules[index]);
  12130. }
  12131. }
  12132. s += ")";
  12133. if (s === "()") {
  12134. return ""; // ignore groups that don't have rules
  12135. }
  12136. return s;
  12137. }
  12138. return getStringForGroup(p.filter);
  12139. };
  12140. // Here we init the filter
  12141. this.reDraw();
  12142. if (p.showQuery) {
  12143. this.onchange();
  12144. }
  12145. // mark is as created so that it will not be created twice on this element
  12146. this.filter = true;
  12147. });
  12148. };
  12149. $.extend($.fn.jqFilter, {
  12150. /*
  12151. * Return SQL like string. Can be used directly
  12152. */
  12153. toSQLString: function () {
  12154. var s = "";
  12155. this.each(function () {
  12156. s = this.toUserFriendlyString();
  12157. });
  12158. return s;
  12159. },
  12160. /*
  12161. * Return filter data as object.
  12162. */
  12163. filterData: function () {
  12164. var s;
  12165. this.each(function () {
  12166. s = this.p.filter;
  12167. });
  12168. return s;
  12169. },
  12170. getParameter: function (param) {
  12171. if (param !== undefined) {
  12172. if (this.p.hasOwnProperty(param)) {
  12173. return this.p[param];
  12174. }
  12175. }
  12176. return this.p;
  12177. },
  12178. resetFilter: function () {
  12179. return this.each(function () {
  12180. this.resetFilter();
  12181. });
  12182. },
  12183. addFilter: function (pfilter) {
  12184. if (typeof pfilter === "string") {
  12185. pfilter = $.parseJSON(pfilter);
  12186. }
  12187. this.each(function () {
  12188. this.p.filter = pfilter;
  12189. this.reDraw();
  12190. this.onchange();
  12191. });
  12192. }
  12193. });
  12194. // end module grid.filter
  12195. /**
  12196. The below work is licensed under Creative Commons GNU LGPL License.
  12197. Original work:
  12198. License: http://creativecommons.org/licenses/LGPL/2.1/
  12199. Author: Stefan Goessner/2006
  12200. Web: http://goessner.net/
  12201. Modifications made:
  12202. Version: 0.9-p5
  12203. Description: Restructured code, JSLint validated (no strict whitespaces),
  12204. added handling of empty arrays, empty strings, and int/floats values.
  12205. Author: Michael Schøler/2008-01-29
  12206. Web: http://michael.hinnerup.net/blog/2008/01/26/converting-json-to-xml-and-xml-to-json/
  12207. Description: json2xml added support to convert functions as CDATA
  12208. so it will be easy to write characters that cause some problems when convert
  12209. Author: Tony Tomov
  12210. */
  12211. // begin module jsonxml
  12212. var xmlJsonClass = {
  12213. // Param "xml": Element or document DOM node.
  12214. // Param "tab": Tab or indent string for pretty output formatting omit or use empty string "" to supress.
  12215. // Returns: JSON string
  12216. xml2json: function (xml, tab) {
  12217. if (xml.nodeType === 9) {
  12218. // document node
  12219. xml = xml.documentElement;
  12220. }
  12221. var nws = this.removeWhite(xml),
  12222. obj = this.toObj(nws),
  12223. json = this.toJson(obj, xml.nodeName, "\t");
  12224. return "{\n" + tab + (tab ? json.replace(/\t/g, tab) : json.replace(/\t|\n/g, "")) + "\n}";
  12225. },
  12226. // Param "o": JavaScript object
  12227. // Param "tab": tab or indent string for pretty output formatting omit or use empty string "" to supress.
  12228. // Returns: XML string
  12229. json2xml: function (o, tab) {
  12230. var toXml = function (v, name, ind) {
  12231. var xml = "", i, n, sXml, hasChild, m;
  12232. if (v instanceof Array) {
  12233. if (v.length === 0) {
  12234. xml += ind + "<" + name + ">__EMPTY_ARRAY_</" + name + ">\n";
  12235. } else {
  12236. for (i = 0, n = v.length; i < n; i += 1) {
  12237. sXml = ind + toXml(v[i], name, ind + "\t") + "\n";
  12238. xml += sXml;
  12239. }
  12240. }
  12241. } else if (typeof v === "object") {
  12242. hasChild = false;
  12243. xml += ind + "<" + name;
  12244. for (m in v) {
  12245. if (v.hasOwnProperty(m)) {
  12246. if (m.charAt(0) === "@") {
  12247. xml += " " + m.substr(1) + "=\"" + v[m].toString() + "\"";
  12248. } else {
  12249. hasChild = true;
  12250. }
  12251. }
  12252. }
  12253. xml += hasChild ? ">" : "/>";
  12254. if (hasChild) {
  12255. for (m in v) {
  12256. if (v.hasOwnProperty(m)) {
  12257. if (m === "#text") {
  12258. xml += v[m];
  12259. } else if (m === "#cdata") {
  12260. xml += "<![CDATA[" + v[m] + "]]>";
  12261. } else if (m.charAt(0) !== "@") {
  12262. xml += toXml(v[m], m, ind + "\t");
  12263. }
  12264. }
  12265. }
  12266. xml += (xml.charAt(xml.length - 1) === "\n" ? ind : "") + "</" + name + ">";
  12267. }
  12268. } else if (typeof v === "function") {
  12269. xml += ind + "<" + name + ">" + "<![CDATA[" + v + "]]>" + "</" + name + ">";
  12270. } else {
  12271. if (v === undefined) {
  12272. v = "";
  12273. }
  12274. if (v.toString() === "\"\"" || v.toString().length === 0) {
  12275. xml += ind + "<" + name + ">__EMPTY_STRING_</" + name + ">";
  12276. } else {
  12277. xml += ind + "<" + name + ">" + v.toString() + "</" + name + ">";
  12278. }
  12279. }
  12280. return xml;
  12281. },
  12282. xml1 = "",
  12283. p;
  12284. for (p in o) {
  12285. if (o.hasOwnProperty(p)) {
  12286. xml1 += toXml(o[p], p, "");
  12287. }
  12288. }
  12289. return tab ? xml1.replace(/\t/g, tab) : xml1.replace(/\t|\n/g, "");
  12290. },
  12291. // Internal methods
  12292. toObj: function (xml) {
  12293. var o = {}, funcTest = /function/i, i, textChild = 0, cdataChild = 0, hasElementChild = false, n;
  12294. if (xml.nodeType === 1) {
  12295. // element node ..
  12296. if (xml.attributes.length) {
  12297. // element with attributes ..
  12298. for (i = 0; i < xml.attributes.length; i += 1) {
  12299. o["@" + xml.attributes[i].nodeName] = (xml.attributes[i].nodeValue || "").toString();
  12300. }
  12301. }
  12302. if (xml.firstChild) {
  12303. // element has child nodes ..
  12304. for (n = xml.firstChild; n; n = n.nextSibling) {
  12305. if (n.nodeType === 1) {
  12306. hasElementChild = true;
  12307. } else if (n.nodeType === 3 && n.nodeValue.match(/[^ \f\n\r\t\v]/)) {
  12308. // non-whitespace text
  12309. textChild += 1;
  12310. } else if (n.nodeType === 4) {
  12311. // cdata section node
  12312. cdataChild += 1;
  12313. }
  12314. }
  12315. if (hasElementChild) {
  12316. if (textChild < 2 && cdataChild < 2) {
  12317. // structured element with evtl. a single text or/and cdata node ..
  12318. this.removeWhite(xml);
  12319. for (n = xml.firstChild; n; n = n.nextSibling) {
  12320. if (n.nodeType === 3) {
  12321. // text node
  12322. o["#text"] = this.escape(n.nodeValue);
  12323. } else if (n.nodeType === 4) {
  12324. // cdata node
  12325. if (funcTest.test(n.nodeValue)) {
  12326. o[n.nodeName] = [o[n.nodeName], n.nodeValue];
  12327. } else {
  12328. o["#cdata"] = this.escape(n.nodeValue);
  12329. }
  12330. } else if (o[n.nodeName]) {
  12331. // multiple occurence of element ..
  12332. if (o[n.nodeName] instanceof Array) {
  12333. o[n.nodeName][o[n.nodeName].length] = this.toObj(n);
  12334. } else {
  12335. o[n.nodeName] = [o[n.nodeName], this.toObj(n)];
  12336. }
  12337. } else {
  12338. // first occurence of element ..
  12339. o[n.nodeName] = this.toObj(n);
  12340. }
  12341. }
  12342. } else {
  12343. // mixed content
  12344. if (!xml.attributes.length) {
  12345. o = this.escape(this.innerXml(xml));
  12346. } else {
  12347. o["#text"] = this.escape(this.innerXml(xml));
  12348. }
  12349. }
  12350. } else if (textChild) {
  12351. // pure text
  12352. if (!xml.attributes.length) {
  12353. o = this.escape(this.innerXml(xml));
  12354. if (o === "__EMPTY_ARRAY_") {
  12355. o = "[]";
  12356. } else if (o === "__EMPTY_STRING_") {
  12357. o = "";
  12358. }
  12359. } else {
  12360. o["#text"] = this.escape(this.innerXml(xml));
  12361. }
  12362. } else if (cdataChild) {
  12363. // cdata
  12364. if (cdataChild > 1) {
  12365. o = this.escape(this.innerXml(xml));
  12366. } else {
  12367. for (n = xml.firstChild; n; n = n.nextSibling) {
  12368. if (funcTest.test(xml.firstChild.nodeValue)) {
  12369. o = xml.firstChild.nodeValue;
  12370. break;
  12371. }
  12372. o["#cdata"] = this.escape(n.nodeValue);
  12373. }
  12374. }
  12375. }
  12376. }
  12377. if (!xml.attributes.length && !xml.firstChild) {
  12378. o = null;
  12379. }
  12380. } else if (xml.nodeType === 9) {
  12381. // document.node
  12382. o = this.toObj(xml.documentElement);
  12383. } else {
  12384. ($.jgrid != null && $.jgrid.defaults != null && $.isFunction($.jgrid.defaults.fatalError) ? $.jgrid.defaults.fatalError : alert)("unhandled node type: " + xml.nodeType);
  12385. }
  12386. return o;
  12387. },
  12388. toJson: function (o, name, ind, wellform) {
  12389. if (wellform === undefined) {
  12390. wellform = true;
  12391. }
  12392. var json = name ? ("\"" + name + "\"") : "", tab = "\t", newline = "\n", n, i, ar = [], arr = [], m;
  12393. if (!wellform) {
  12394. tab = "";
  12395. newline = "";
  12396. }
  12397. if (o === "[]") {
  12398. json += (name ? ":[]" : "[]");
  12399. } else if (o instanceof Array) {
  12400. for (i = 0, n = o.length; i < n; i += 1) {
  12401. ar[i] = this.toJson(o[i], "", ind + tab, wellform);
  12402. }
  12403. json += (name ? ":[" : "[") + (ar.length > 1 ? (newline + ind + tab + ar.join("," + newline + ind + tab) + newline + ind) : ar.join("")) + "]";
  12404. } else if (o === null) {
  12405. json += (name && ":") + "null";
  12406. } else if (typeof o === "object") {
  12407. for (m in o) {
  12408. if (o.hasOwnProperty(m)) {
  12409. arr[arr.length] = this.toJson(o[m], m, ind + tab, wellform);
  12410. }
  12411. }
  12412. json += (name ? ":{" : "{") + (arr.length > 1 ? (newline + ind + tab + arr.join("," + newline + ind + tab) + newline + ind) : arr.join("")) + "}";
  12413. } else if (typeof o === "string") {
  12414. json += (name && ":") + "\"" + o.replace(/\\/g, "\\\\").replace(/\"/g, '\\"') + "\"";
  12415. } else {
  12416. json += (name && ":") + o.toString();
  12417. }
  12418. return json;
  12419. },
  12420. innerXml: function (node) {
  12421. var s = "", child,
  12422. asXml = function (n) {
  12423. var str = "", i, c;
  12424. if (n.nodeType === 1) {
  12425. str += "<" + n.nodeName;
  12426. for (i = 0; i < n.attributes.length; i += 1) {
  12427. str += " " + n.attributes[i].nodeName + "=\"" + (n.attributes[i].nodeValue || "").toString() + "\"";
  12428. }
  12429. if (n.firstChild) {
  12430. str += ">";
  12431. for (c = n.firstChild; c; c = c.nextSibling) {
  12432. str += asXml(c);
  12433. }
  12434. str += "</" + n.nodeName + ">";
  12435. } else {
  12436. str += "/>";
  12437. }
  12438. } else if (n.nodeType === 3) {
  12439. str += n.nodeValue;
  12440. } else if (n.nodeType === 4) {
  12441. str += "<![CDATA[" + n.nodeValue + "]]>";
  12442. }
  12443. return str;
  12444. };
  12445. if (node.hasOwnProperty("innerHTML")) {
  12446. s = node.innerHTML;
  12447. } else {
  12448. for (child = node.firstChild; child; child = child.nextSibling) {
  12449. s += asXml(child);
  12450. }
  12451. }
  12452. return s;
  12453. },
  12454. escape: function (txt) {
  12455. return txt.replace(/[\\]/g, "\\\\").replace(/[\"]/g, '\\"').replace(/[\n]/g, "\\n").replace(/[\r]/g, "\\r");
  12456. },
  12457. removeWhite: function (e) {
  12458. e.normalize();
  12459. var n = e.firstChild, nxt;
  12460. while (n) {
  12461. if (n.nodeType === 3) {
  12462. // text node
  12463. if (!n.nodeValue.match(/[^ \f\n\r\t\v]/)) {
  12464. // pure whitespace text node
  12465. nxt = n.nextSibling;
  12466. e.removeChild(n);
  12467. n = nxt;
  12468. } else {
  12469. n = n.nextSibling;
  12470. }
  12471. } else if (n.nodeType === 1) {
  12472. // element node
  12473. this.removeWhite(n);
  12474. n = n.nextSibling;
  12475. } else {
  12476. // any other node
  12477. n = n.nextSibling;
  12478. }
  12479. }
  12480. return e;
  12481. }
  12482. };
  12483. window.xmlJsonClass = xmlJsonClass;
  12484. // end module jsonxml
  12485. /**
  12486. * jqGrid extension for form editing Grid Data
  12487. * Copyright (c) 2008-2014, Tony Tomov, tony@trirand.com, http://trirand.com/blog/
  12488. * Copyright (c) 2014-2018, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  12489. * Dual licensed under the MIT and GPL licenses:
  12490. * http://www.opensource.org/licenses/mit-license.php
  12491. * http://www.gnu.org/licenses/gpl-2.0.html
  12492. **/
  12493. // begin module grid.formedit
  12494. var jgridFeedback = jgrid.feedback, fullBoolFeedback = jgrid.fullBoolFeedback, builderFmButon = jgrid.builderFmButon,
  12495. addFormIcon = function ($fmButton, iconInfos, commonIcon) {
  12496. var iconspan;
  12497. if (iconInfos[0] === true) {
  12498. iconspan = "<span class='" + mergeCssClasses("fm-button-icon", commonIcon, iconInfos[2]) + "'></span>";
  12499. if (iconInfos[1] === "right") {
  12500. $fmButton.addClass("fm-button-icon-right").append(iconspan);
  12501. } else {
  12502. $fmButton.addClass("fm-button-icon-left").prepend(iconspan);
  12503. }
  12504. }
  12505. },
  12506. getGuiStateStyles = function (path) {
  12507. return getGuiStyles.call(this, "states." + path);
  12508. },
  12509. hideRowsWithoutVissibleCells = function ($tb) {
  12510. $tb.find("tr[data-rowpos]").each(function () {
  12511. var vissible = 0;
  12512. $(this).children("td").each(function () {
  12513. if ($(this).css("visibility") !== "hidden") {
  12514. vissible++;
  12515. }
  12516. });
  12517. if (!vissible) {
  12518. $(this).hide();
  12519. }
  12520. });
  12521. },
  12522. isEmptyString = function (htmlStr) {
  12523. return htmlStr === "&nbsp;" || htmlStr === "&#160;" || (htmlStr.length === 1 && htmlStr.charCodeAt(0) === 160);
  12524. };
  12525. jgrid.extend({
  12526. searchGrid: function (oMuligrid) {
  12527. // if one uses jQuery wrapper with multiple grids, then oMuligrid specify the object with common options
  12528. return this.each(function () {
  12529. var $t = this, $self = $($t), p = $t.p;
  12530. if (!$t.grid || p == null) { return; }
  12531. // make new copy of the options and use it for ONE specific grid.
  12532. // p.searching can contains grid specific options
  12533. // we will don't modify the input options oMuligrid
  12534. var o = $.extend(true,
  12535. {
  12536. drag: true,
  12537. sField: "searchField",
  12538. sValue: "searchString",
  12539. sOper: "searchOper",
  12540. sFilter: p.prmNames.filters,
  12541. loadDefaults: true, // this options activates loading of default filters from grid's postData for Multipe Search only.
  12542. beforeShowSearch: null,
  12543. afterShowSearch: null,
  12544. onInitializeSearch: null,
  12545. afterRedraw: null,
  12546. afterChange: null,
  12547. closeAfterSearch: false,
  12548. closeAfterReset: false,
  12549. closeOnEscape: false,
  12550. searchOnEnter: false,
  12551. multipleSearch: false,
  12552. multipleGroup: false,
  12553. // we can't use srort names like resetIcon because of conflict with existing "x" of filterToolbar
  12554. top: 0,
  12555. left: 0,
  12556. removemodal: true,
  12557. //jqModal : true,
  12558. //modal: false,
  12559. resize: true,
  12560. width: 450,
  12561. height: "auto",
  12562. dataheight: "auto",
  12563. showQuery: false,
  12564. errorcheck: true,
  12565. sopt: null,
  12566. stringResult: undefined,
  12567. onClose: null,
  12568. onSearch: null,
  12569. onReset: null,
  12570. //toTop : false,
  12571. //overlay : 30,
  12572. columns: [],
  12573. tmplNames: null,
  12574. tmplFilters: null,
  12575. tmplLabel: " Template: ",
  12576. showOnLoad: false,
  12577. layer: null,
  12578. operands: {
  12579. eq: "=",
  12580. ne: "<>",
  12581. lt: "<",
  12582. le: "<=",
  12583. gt: ">",
  12584. ge: ">=",
  12585. bw: "LIKE",
  12586. bn: "NOT LIKE",
  12587. "in": "IN",
  12588. ni: "NOT IN",
  12589. ew: "LIKE",
  12590. en: "NOT LIKE",
  12591. cn: "LIKE",
  12592. nc: "NOT LIKE",
  12593. nu: "IS NULL",
  12594. nn: "IS NOT NULL"
  12595. }
  12596. },
  12597. base.getGridRes.call($self, "search"),
  12598. jgrid.search || {},
  12599. p.searching || {},
  12600. oMuligrid || {});
  12601. var fid = "fbox_" + p.id, commonIconClass = o.commonIconClass,
  12602. ids = { themodal: "searchmod" + fid, modalhead: "searchhd" + fid, modalcontent: "searchcnt" + fid, resizeAlso: fid },
  12603. themodalSelector = "#" + jqID(ids.themodal), gboxSelector = p.gBox, gviewSelector = p.gView, each = $.each,
  12604. defaultFilters = p.postData[o.sFilter],
  12605. searchFeedback = function () {
  12606. var args = $.makeArray(arguments);
  12607. args.unshift("Search");
  12608. args.unshift("Filter");
  12609. args.unshift(o);
  12610. return jgridFeedback.apply($t, args);
  12611. },
  12612. hideModel = function () {
  12613. jgrid.hideModal(themodalSelector, {
  12614. gb: gboxSelector,
  12615. jqm: o.jqModal,
  12616. onClose: o.onClose,
  12617. removemodal: o.removemodal
  12618. });
  12619. };
  12620. if (typeof defaultFilters === "string") {
  12621. defaultFilters = $.trim(defaultFilters) !== "" ? $.parseJSON(defaultFilters) : undefined;
  12622. }
  12623. $(themodalSelector).remove();
  12624. function showFilter($filter) {
  12625. if (searchFeedback("beforeShow", $filter)) {
  12626. $(themodalSelector).data("onClose", o.onClose);
  12627. jgrid.viewModal.call($t, themodalSelector, {
  12628. gbox: gboxSelector,
  12629. jqm: o.jqModal,
  12630. overlay: o.overlay,
  12631. modal: o.modal,
  12632. overlayClass: o.overlayClass,
  12633. toTop: o.toTop,
  12634. onHide: function (h) {
  12635. h.w.remove();
  12636. if (h.o) { h.o.remove(); }
  12637. }
  12638. });
  12639. searchFeedback("afterShow", $filter);
  12640. }
  12641. }
  12642. if ($(themodalSelector)[0] !== undefined) {
  12643. showFilter($("#fbox_" + jqID(p.id)));
  12644. } else {
  12645. var fil = $("<div><div id='" + fid + "' class='" +
  12646. getGuiStyles.call($t, "dialog.body", "searchFilter") +
  12647. "' style='overflow:auto'></div></div>").insertBefore(gviewSelector);
  12648. if (p.direction === "rtl") {
  12649. fil.attr("dir", "rtl");
  12650. }
  12651. var bQ = "", tmpl = "", colnm, found = false, bt, cmi = -1, columns = $.extend([], p.colModel),
  12652. bS = builderFmButon.call($t, fid + "_search", o.Find, mergeCssClasses(commonIconClass, o.findDialogIcon), "right"),
  12653. bC = builderFmButon.call($t, fid + "_reset", o.Reset, mergeCssClasses(commonIconClass, o.resetDialogIcon), "left");
  12654. if (o.showQuery) {
  12655. bQ = builderFmButon.call($t, fid + "_query", "Query", mergeCssClasses(commonIconClass, o.queryDialogIcon), "left") +
  12656. "&#160;";
  12657. }
  12658. if (o.searchForAdditionalProperties) {
  12659. each(p.additionalProperties, function () {
  12660. var cm = typeof this === "string" ? { name: this } : this;
  12661. if (!cm.label) {
  12662. cm.label = cm.name;
  12663. }
  12664. cm.isAddProp = true,
  12665. columns.push(cm);
  12666. });
  12667. }
  12668. if (!o.columns.length) {
  12669. each(columns, function (i, n) {
  12670. if (!n.label) {
  12671. n.label = n.isAddProp ? n.name : p.colNames[i];
  12672. }
  12673. // find first searchable column and set it if no default filter
  12674. if (!found) {
  12675. var searchable = (n.search === undefined) ? true : n.search,
  12676. hidden = (n.hidden === true),
  12677. ignoreHiding = (n.searchoptions && n.searchoptions.searchhidden === true);
  12678. if ((ignoreHiding && searchable) || (searchable && !hidden)) {
  12679. found = true;
  12680. colnm = n.index || n.name;
  12681. cmi = i;
  12682. }
  12683. }
  12684. });
  12685. } else {
  12686. columns = o.columns;
  12687. cmi = 0;
  12688. colnm = columns[0].index || columns[0].name;
  12689. }
  12690. // old behaviour
  12691. if ((!defaultFilters && colnm) || o.multipleSearch === false) {
  12692. var cmop = "eq";
  12693. if (cmi >= 0 && columns[cmi].searchoptions && columns[cmi].searchoptions.sopt) {
  12694. cmop = columns[cmi].searchoptions.sopt[0];
  12695. } else if (o.sopt && o.sopt.length) {
  12696. cmop = o.sopt[0];
  12697. }
  12698. defaultFilters = { groupOp: "AND", rules: [{ field: colnm, op: cmop, data: "" }] };
  12699. }
  12700. found = false;
  12701. if (o.tmplNames && o.tmplNames.length) {
  12702. found = true;
  12703. tmpl = o.tmplLabel;
  12704. tmpl += "<select class='ui-template'>";
  12705. tmpl += "<option value='default'>Default</option>";
  12706. each(o.tmplNames, function (i, n) {
  12707. tmpl += "<option value='" + i + "'>" + n + "</option>";
  12708. });
  12709. tmpl += "</select>";
  12710. }
  12711. bt = "<div class='" + getGuiStyles.call($t, "dialog.footer") + "'><table class='EditTable' style='border:0px none;margin-top:5px' id='" + fid + "_2'><tbody><tr><td colspan='2'><hr class='" +
  12712. getGuiStyles.call($t, "dialog.hr") + "' style='margin:1px'/></td></tr><tr><td class='EditButton EditButton-" + p.direction + "' style='float:" + (p.direction === "rtl" ? "right" : "left") + ";'>" + bC + tmpl + "</td><td class='EditButton EditButton-" + p.direction + "'>" + bQ + bS + "</td></tr></tbody></table></div>";
  12713. fid = jqID(fid);
  12714. o.gbox = gboxSelector; //"#gbox_" + fid;
  12715. o.height = "auto";
  12716. fid = "#" + fid;
  12717. $(fid).jqFilter({
  12718. columns: columns,
  12719. filter: o.loadDefaults ? defaultFilters : null,
  12720. showQuery: o.showQuery,
  12721. errorcheck: o.errorcheck,
  12722. sopt: o.sopt,
  12723. groupButton: o.multipleGroup,
  12724. ruleButtons: o.multipleSearch,
  12725. afterRedraw: o.afterRedraw,
  12726. ops: o.odata,
  12727. cops: p.customSortOperations,
  12728. operands: o.operands,
  12729. ajaxSelectOptions: p.ajaxSelectOptions,
  12730. groupOps: o.groupOps,
  12731. onChange: function (filterOptions, filterDiv) {
  12732. if (filterOptions.showQuery) {
  12733. $(".query", filterDiv).text(filterDiv.toUserFriendlyString());
  12734. }
  12735. fullBoolFeedback.call($t, o.afterChange, "jqGridFilterAfterChange", $(fid), o, filterOptions, filterDiv);
  12736. },
  12737. direction: p.direction,
  12738. id: p.id
  12739. });
  12740. fil.append(bt);
  12741. if (found && o.tmplFilters && o.tmplFilters.length) {
  12742. $(".ui-template", fil).on("change", function () {
  12743. var curtempl = $(this).val();
  12744. if (curtempl === "default") {
  12745. $(fid).jqFilter("addFilter", defaultFilters);
  12746. } else {
  12747. $(fid).jqFilter("addFilter", o.tmplFilters[parseInt(curtempl, 10)]);
  12748. }
  12749. return false;
  12750. });
  12751. }
  12752. if (o.multipleGroup === true) { o.multipleSearch = true; }
  12753. searchFeedback("onInitialize", $(fid));
  12754. if (o.layer) {
  12755. jgrid.createModal.call($t, ids, fil, o, gviewSelector, $(gboxSelector)[0], "#" + jqID(o.layer), { position: "relative" });
  12756. } else {
  12757. jgrid.createModal.call($t, ids, fil, o, gviewSelector, $(gboxSelector)[0]);
  12758. }
  12759. if (o.searchOnEnter || o.closeOnEscape) {
  12760. $(themodalSelector).keydown(function (e) {
  12761. var $target = $(e.target);
  12762. if (o.searchOnEnter && e.which === 13 && // 13 === $.ui.keyCode.ENTER
  12763. !$target.hasClass("add-group") && !$target.hasClass("add-rule") &&
  12764. !$target.hasClass("delete-group") && !$target.hasClass("delete-rule") &&
  12765. (!$target.hasClass("fm-button") || !$target.is("[id$=_query]"))) {
  12766. $(fid + "_search").click();
  12767. return false;
  12768. }
  12769. if (o.closeOnEscape && e.which === 27) { // 27 === $.ui.keyCode.ESCAPE
  12770. $("#" + jqID(ids.modalhead)).find(".ui-jqdialog-titlebar-close").click();
  12771. return false;
  12772. }
  12773. });
  12774. }
  12775. if (bQ) {
  12776. $(fid + "_query").on("click", function () {
  12777. $(".queryresult", fil).toggle();
  12778. return false;
  12779. });
  12780. }
  12781. if (o.stringResult === undefined) {
  12782. // to provide backward compatibility, inferring stringResult value from multipleSearch
  12783. o.stringResult = o.multipleSearch;
  12784. }
  12785. $(fid + "_search").on("click", function () {
  12786. var sdata = {}, res = "", filters, fl = $(fid), $inputs = fl.find(".input-elm");
  12787. if ($inputs.filter(":focus")) {
  12788. $inputs = $inputs.filter(":focus");
  12789. }
  12790. $inputs.change();
  12791. filters = fl.jqFilter("filterData");
  12792. if (o.errorcheck) {
  12793. fl[0].hideError();
  12794. if (!o.showQuery) { fl.jqFilter("toSQLString"); }
  12795. if (fl[0].p.error) {
  12796. fl[0].showError();
  12797. return false;
  12798. }
  12799. }
  12800. if (o.stringResult || p.datatype === "local") {
  12801. try {
  12802. res = JSON.stringify(filters);
  12803. } catch (ignore) { }
  12804. if (typeof res === "string") {
  12805. sdata[o.sFilter] = res;
  12806. each([o.sField, o.sValue, o.sOper], function () { sdata[this] = ""; });
  12807. }
  12808. } else {
  12809. if (o.multipleSearch) {
  12810. sdata[o.sFilter] = filters;
  12811. each([o.sField, o.sValue, o.sOper], function () { sdata[this] = ""; });
  12812. } else {
  12813. sdata[o.sField] = filters.rules[0].field;
  12814. sdata[o.sValue] = filters.rules[0].data;
  12815. sdata[o.sOper] = filters.rules[0].op;
  12816. sdata[o.sFilter] = "";
  12817. }
  12818. }
  12819. $.extend(p.postData, sdata);
  12820. if (fullBoolFeedback.call($t, o.onSearch, "jqGridFilterSearch", p.filters)) {
  12821. p.search = true;
  12822. $self.trigger("reloadGrid", [$.extend({ page: 1 }, o.reloadGridSearchOptions || {})]);
  12823. }
  12824. if (o.closeAfterSearch) {
  12825. hideModel();
  12826. }
  12827. return false;
  12828. });
  12829. $(fid + "_reset").on("click", function () {
  12830. var sdata = {}, fl1 = $(fid);
  12831. p.search = false;
  12832. p.resetsearch = true;
  12833. if (o.multipleSearch === false) {
  12834. sdata[o.sField] = sdata[o.sValue] = sdata[o.sOper] = "";
  12835. } else {
  12836. sdata[o.sFilter] = "";
  12837. }
  12838. fl1[0].resetFilter();
  12839. if (found) {
  12840. $(".ui-template", fil).val("default");
  12841. }
  12842. $.extend(p.postData, sdata);
  12843. if (fullBoolFeedback.call($t, o.onReset, "jqGridFilterReset")) {
  12844. $self.trigger("reloadGrid", [$.extend({ page: 1 }, o.reloadGridResetOptions || {})]);
  12845. }
  12846. if (o.closeAfterReset) {
  12847. hideModel();
  12848. }
  12849. return false;
  12850. });
  12851. showFilter($(fid));
  12852. var hoverClasses = getGuiStateStyles.call($t, "hover");
  12853. // !!! The next row will not work if "states.disabled" is defined using more as one CSS class
  12854. $(".fm-button:not(." + getGuiStateStyles.call($t, "disabled").split(" ").join(".") + ")", fil).hover(
  12855. function () { $(this).addClass(hoverClasses); },
  12856. function () { $(this).removeClass(hoverClasses); }
  12857. );
  12858. }
  12859. });
  12860. },
  12861. editGridRow: function (rowid, oMuligrid) { // if one uses jQuery wrapper with multiple grids, then oMultiple specify the object with common options
  12862. return this.each(function () {
  12863. var $t = this, $self = $($t), p = $t.p;
  12864. if (!$t.grid || p == null || !rowid) { return; }
  12865. // make new copy of the options oMuligrid and use it for ONE specific grid.
  12866. // p.formEditing can contains grid specific options
  12867. // we will don't modify the input options oMuligrid
  12868. var gridId = p.id, getGridRes = base.getGridRes, setSelection = base.setSelection,
  12869. o = $.extend(true,
  12870. {
  12871. top: 0,
  12872. left: 0,
  12873. width: 300,
  12874. datawidth: "auto",
  12875. height: "auto",
  12876. dataheight: "auto",
  12877. //modal: false,
  12878. //toTop : false,
  12879. //overlay : 30,
  12880. drag: true,
  12881. resize: true,
  12882. url: null,
  12883. mtype: "POST",
  12884. clearAfterAdd: true,
  12885. closeAfterEdit: false,
  12886. reloadAfterSubmit: true,
  12887. onInitializeForm: null,
  12888. beforeInitData: null,
  12889. beforeShowForm: null,
  12890. afterShowForm: null,
  12891. beforeSubmit: null,
  12892. afterSubmit: null,
  12893. onclickSubmit: null,
  12894. afterComplete: null,
  12895. onclickPgButtons: null,
  12896. afterclickPgButtons: null,
  12897. editData: {},
  12898. //jqModal : true,
  12899. closeOnEscape: false,
  12900. addedrow: "first",
  12901. topinfo: "",
  12902. bottominfo: "",
  12903. labelswidth: "",
  12904. savekey: [false, 13],
  12905. navkeys: [false, 38, 40],
  12906. checkOnSubmit: false,
  12907. checkOnUpdate: false,
  12908. _savedData: {},
  12909. processing: false,
  12910. onClose: null,
  12911. ajaxEditOptions: {},
  12912. serializeEditData: null,
  12913. viewPagerButtons: true,
  12914. overlayClass: getGuiStyles.call(this, "overlay"),
  12915. removemodal: true,
  12916. skipPostTypes: ["image", "file"],
  12917. saveui: "enable",
  12918. savetext: getGridRes.call($self, "defaults.savetext") || "Saving..."
  12919. },
  12920. getGridRes.call($self, "edit"),
  12921. jgrid.edit,
  12922. p.formEditing || {},
  12923. oMuligrid || {});
  12924. var frmgr = "FrmGrid_" + gridId, frmgrId = frmgr, frmtborg = "TblGrid_" + gridId, frmtb = "#" + jqID(frmtborg), frmtb2 = frmtb + "_2",
  12925. ids = { themodal: "editmod" + gridId, modalhead: "edithd" + gridId, modalcontent: "editcnt" + gridId, resizeAlso: frmgr },
  12926. themodalSelector = "#" + jqID(ids.themodal), gboxSelector = p.gBox, colModel = p.colModel, iColByName = p.iColByName,
  12927. maxCols = 1, maxRows = 0, postdata, diff, editOrAdd, commonIconClass = o.commonIconClass,
  12928. hideModal = function () {
  12929. jgrid.hideModal(themodalSelector, {
  12930. gb: gboxSelector,
  12931. jqm: o.jqModal,
  12932. onClose: o.onClose,
  12933. removemodal: o.removemodal
  12934. });
  12935. },
  12936. errcap = getGridRes.call($self, "errors.errcap"),
  12937. editFeedback = function () {
  12938. var args = $.makeArray(arguments);
  12939. args.unshift("");
  12940. args.unshift("AddEdit");
  12941. args.unshift(o);
  12942. return jgridFeedback.apply($t, args);
  12943. },
  12944. hoverClasses = getGuiStateStyles.call($t, "hover"),
  12945. disabledClass = getGuiStateStyles.call($t, "disabled"),
  12946. highlightClass = getGuiStateStyles.call($t, "select"),
  12947. activeClass = getGuiStateStyles.call($t, "active"),
  12948. errorClass = getGuiStateStyles.call($t, "error");
  12949. $(themodalSelector).remove();
  12950. frmgr = "#" + jqID(frmgr);
  12951. if (rowid === "new") {
  12952. rowid = "_empty";
  12953. editOrAdd = "add";
  12954. o.caption = o.addCaption;
  12955. } else {
  12956. o.caption = o.editCaption;
  12957. editOrAdd = "edit";
  12958. }
  12959. var closeovrl = true;
  12960. if (o.checkOnUpdate && (o.jqModal === true || o.jqModal === undefined) && !o.modal) {
  12961. closeovrl = false;
  12962. }
  12963. function getFormData() {
  12964. $(frmtb + " > tbody > tr > td .FormElement").each(function () {
  12965. var $celm = $(".customelement", this),
  12966. nm = $celm.length ? $celm.attr("name") : this.name,
  12967. iCol = iColByName[nm],
  12968. cm = iCol !== undefined ? colModel[iCol] || {} : {},
  12969. editoptions = cm.editoptions || {},
  12970. formatoptions, newformat, type;
  12971. if ($celm.length && $.isFunction(editoptions.custom_value)) {
  12972. try {
  12973. postdata[nm] = editoptions.custom_value.call($t, $("#" + jqID(nm), frmtb), "get");
  12974. if (postdata[nm] === undefined) { throw "e1"; }
  12975. } catch (e) {
  12976. if (e === "e1") {
  12977. jgrid.info_dialog.call($t, errcap, "function 'custom_value' " + o.msg.novalue, o.bClose);
  12978. } else {
  12979. jgrid.info_dialog.call($t, errcap, e.message, o.bClose);
  12980. }
  12981. }
  12982. return true;
  12983. } else {
  12984. type = $(this)[0].type;
  12985. switch (type) {
  12986. case "checkbox":
  12987. var checkBoxValues = typeof editoptions.value === "string" ?
  12988. editoptions.value.split(":") :
  12989. ["Yes", "No"];
  12990. postdata[nm] = $(this).is(":checked") ? checkBoxValues[0] : checkBoxValues[1];
  12991. break;
  12992. case "select-one":
  12993. postdata[nm] = $("option:selected", this).val();
  12994. break;
  12995. case "select-multiple":
  12996. postdata[nm] = $(this).val();
  12997. postdata[nm] = postdata[nm] ? postdata[nm].join(",") : "";
  12998. var selectedText = [];
  12999. $("option:selected", this).each(
  13000. function (i, selected) {
  13001. selectedText[i] = $(selected).text();
  13002. }
  13003. );
  13004. break;
  13005. case "date":
  13006. postdata[nm] = $(this).val();
  13007. if (String(postdata[nm]).split("-").length === 3) {
  13008. formatoptions = cm.formatoptions || {};
  13009. newformat = formatoptions.newformat || getGridRes.call($self, "formatter.date.newformat");
  13010. postdata[nm] = jgrid.parseDate.call($self[0], "Y-m-d", postdata[nm], newformat);
  13011. }
  13012. break;
  13013. default:
  13014. if (type !== undefined && $.inArray(type, o.skipPostTypes) < 0) {
  13015. postdata[nm] = $(this).val();
  13016. }
  13017. break;
  13018. }
  13019. }
  13020. });
  13021. return true;
  13022. }
  13023. function createData(rowid1, tb, maxcols) {
  13024. var cnt = 0, retpos = [], ind = false, $tb = $(tb),
  13025. labelsWidth = String(o.labelswidth) + (!o.labelswidth || isNaN(o.labelswidth) ? "" : "px"),
  13026. tdtmpl = "<td class='CaptionTD" +
  13027. (labelsWidth ? "' style='width:" + labelsWidth + ";" : "") +
  13028. "'>&#160;</td><td class='DataTD'>&#160;</td>", tmpl = "", i; //*2
  13029. for (i = 1; i <= maxcols; i++) {
  13030. tmpl += tdtmpl;
  13031. }
  13032. if (rowid1 !== "_empty") {
  13033. ind = base.getInd.call($self, rowid1);
  13034. }
  13035. $(colModel).each(function (iCol) {
  13036. var cm = this, nm = cm.name, $td, hc, trdata, tmp, elc, editable = cm.editable, disabled = false, readonly = false,
  13037. mode = rowid1 === "_empty" ? "addForm" : "editForm";
  13038. if ($.isFunction(editable)) {
  13039. editable = editable.call($t, {
  13040. rowid: rowid1,
  13041. iCol: iCol,
  13042. iRow: ind, // can be false for Add operation
  13043. cmName: nm,
  13044. cm: cm,
  13045. mode: mode
  13046. });
  13047. }
  13048. // hidden fields are included in the form
  13049. if (cm.editrules && cm.editrules.edithidden === true) {
  13050. hc = false;
  13051. } else {
  13052. hc = cm.hidden === true || editable === "hidden" ? true : false;
  13053. }
  13054. switch (String(editable).toLowerCase()) {
  13055. case "hidden":
  13056. editable = true;
  13057. break;
  13058. case "disabled":
  13059. editable = true;
  13060. disabled = true;
  13061. break;
  13062. case "readonly":
  13063. editable = true;
  13064. readonly = true;
  13065. break;
  13066. }
  13067. if (nm !== "cb" && nm !== "subgrid" && editable === true && nm !== "rn") {
  13068. if (ind === false) {
  13069. tmp = "";
  13070. } else {
  13071. $td = $($t.rows[ind].cells[iCol]); // $("td[role=gridcell]:eq(" + i + ")", $t.rows[ind])
  13072. try {
  13073. tmp = $.unformat.call($t, $td, { rowId: rowid1, colModel: cm }, iCol);
  13074. } catch (_) {
  13075. tmp = (cm.edittype && cm.edittype === "textarea") ? $td.text() : $td.html();
  13076. }
  13077. if (isEmptyString(tmp)) { tmp = ""; }
  13078. }
  13079. var opt = $.extend({}, cm.editoptions || {},
  13080. { id: nm, name: nm, rowId: rowid1, mode: mode, cm: cm, iCol: iCol }),
  13081. frmopt = $.extend({}, { elmprefix: "", elmsuffix: "", rowabove: false, rowcontent: "" }, cm.formoptions || {}),
  13082. rp = parseInt(frmopt.rowpos, 10) || cnt + 1,
  13083. cp = parseInt((parseInt(frmopt.colpos, 10) || 1) * 2, 10);
  13084. if (rowid1 === "_empty" && opt.defaultValue) {
  13085. tmp = $.isFunction(opt.defaultValue) ? opt.defaultValue.call($t) : opt.defaultValue;
  13086. }
  13087. if (!cm.edittype) { cm.edittype = "text"; }
  13088. if (p.autoEncodeOnEdit) { tmp = jgrid.oldDecodePostedData(tmp); }
  13089. elc = jgrid.createEl.call($t, cm.edittype, opt, tmp, false, $.extend({}, jgrid.ajaxOptions, p.ajaxSelectOptions || {}));
  13090. //if(tmp === "" && cm.edittype == "checkbox") {tmp = $(elc).data("offval");}
  13091. //if(tmp === "" && cm.edittype == "select") {tmp = $("option:eq(0)",elc).text();}
  13092. if (o.checkOnSubmit || o.checkOnUpdate) { o._savedData[nm] = tmp; }
  13093. $(elc).addClass("FormElement");
  13094. if ($.inArray(cm.edittype, ["text", "textarea", "checkbox", "password", "select"]) > -1) {
  13095. $(elc).addClass(getGuiStyles.call($t, "dialog.dataField"));
  13096. }
  13097. trdata = $tb.find("tr[data-rowpos=" + rp + "]");
  13098. if (frmopt.rowabove) {
  13099. var newdata = $("<tr><td class='contentinfo' colspan='" + (maxcols * 2) + "'>" + frmopt.rowcontent + "</td></tr>");
  13100. $tb.append(newdata);
  13101. newdata[0].rp = rp;
  13102. }
  13103. if (trdata.length === 0) {
  13104. trdata = $("<tr data-rowpos='" + rp + "'></tr>").addClass("FormData").attr("id", "tr_" + nm);
  13105. $(trdata).append(tmpl);
  13106. $tb.append(trdata);
  13107. trdata[0].rp = rp;
  13108. }
  13109. var $label = $("td:eq(" + (cp - 2) + ")", trdata[0]),
  13110. $data = $("td:eq(" + (cp - 1) + ")", trdata[0]);
  13111. $label.html(frmopt.label === undefined ? p.colNames[iCol] : frmopt.label || "&#160;");
  13112. var $dataCell = $data[isEmptyString($data.html()) ? "html" : "append"](frmopt.elmprefix);
  13113. $dataCell.append(elc).append(frmopt.elmsuffix);
  13114. if (elc.tagName.toUpperCase() === "INPUT" && cm.createColumnIndex && opt.generateDatalist) {
  13115. var $datalist = $self.jqGrid("generateDatalistFromColumnIndex", cm.name);
  13116. if ($datalist != null && $datalist.length > 0) {
  13117. $(elc).attr("list", "dl_" + elc.id);
  13118. $dataCell.append($datalist.attr("id", "dl_" + elc.id));
  13119. }
  13120. }
  13121. if (disabled) {
  13122. $label.addClass(disabledClass);
  13123. $data.addClass(disabledClass);
  13124. $(elc).prop("readonly", true);
  13125. $(elc).prop("disabled", true);
  13126. } else if (readonly) {
  13127. $(elc).prop("readonly", true);
  13128. }
  13129. if (cm.edittype === "custom" && $.isFunction(opt.custom_value)) {
  13130. opt.custom_value.call($t, $("#" + jqID(nm), frmgr), "set", tmp);
  13131. }
  13132. jgrid.bindEv.call($t, elc, opt);
  13133. if (hc) {
  13134. $label.add($data).css("visibility", "hidden");
  13135. }
  13136. retpos[cnt] = iCol;
  13137. cnt++;
  13138. }
  13139. });
  13140. hideRowsWithoutVissibleCells($tb);
  13141. if (cnt > 0) {
  13142. var idrow = $("<tr class='FormData' style='display:none'><td class='CaptionTD'>&#160;</td><td colspan='" + (maxcols * 2 - 1) + "' class='DataTD'><input class='FormElement' id='id_g' type='text' name='" + gridId + "_id' value='" + rowid1 + "'/></td></tr>");
  13143. idrow[0].rp = cnt + 999;
  13144. $tb.append(idrow);
  13145. if (o.checkOnSubmit || o.checkOnUpdate) { o._savedData[gridId + "_id"] = rowid1; }
  13146. }
  13147. return retpos;
  13148. }
  13149. function fillData(rowid1, fmid) {
  13150. var nm, cnt = 0, fld, opt, vl, vlc;
  13151. if (o.checkOnSubmit || o.checkOnUpdate) { o._savedData = {}; o._savedData[gridId + "_id"] = rowid1; }
  13152. var cm = p.colModel;
  13153. if (rowid1 === "_empty") {
  13154. $(cm).each(function () {
  13155. nm = this.name;
  13156. opt = $.extend({}, this.editoptions || {});
  13157. fld = $("#" + jqID(nm), fmid);
  13158. if (fld && fld.length && fld[0] !== null) {
  13159. vl = "";
  13160. if (this.edittype === "custom" && $.isFunction(opt.custom_value)) {
  13161. opt.custom_value.call($t, fld, "set", vl);
  13162. } else if (opt.defaultValue) {
  13163. vl = $.isFunction(opt.defaultValue) ? opt.defaultValue.call($t) : opt.defaultValue;
  13164. if (fld[0].type === "checkbox") {
  13165. vlc = vl.toLowerCase();
  13166. if (vlc.search(/(false|f|0|no|n|off|undefined)/i) < 0 && vlc !== "") {
  13167. fld[0].checked = true;
  13168. fld[0].defaultChecked = true;
  13169. fld[0].value = vl;
  13170. } else {
  13171. fld[0].checked = false;
  13172. fld[0].defaultChecked = false;
  13173. }
  13174. } else { fld.val(vl); }
  13175. } else {
  13176. if (fld[0].type === "checkbox") {
  13177. fld[0].checked = false;
  13178. fld[0].defaultChecked = false;
  13179. vl = $(fld).data("offval");
  13180. } else if (fld[0].type && fld[0].type.substr(0, 6) === "select") {
  13181. fld[0].selectedIndex = 0;
  13182. } else {
  13183. fld.val(vl);
  13184. }
  13185. }
  13186. if (o.checkOnSubmit === true || o.checkOnUpdate) { o._savedData[nm] = vl; }
  13187. }
  13188. });
  13189. $("#id_g", fmid).val(rowid1);
  13190. return;
  13191. }
  13192. var tre = base.getInd.call($self, rowid1, true);
  13193. if (!tre) { return; }
  13194. //$("td[role=gridcell]", tre)
  13195. $(tre.cells).filter("td[role=gridcell]").each(function (i) {
  13196. var tmp;
  13197. nm = cm[i].name;
  13198. // hidden fields are included in the form
  13199. if (nm !== "cb" && nm !== "subgrid" && nm !== "rn" && cm[i].editable === true) {
  13200. try {
  13201. tmp = $.unformat.call($t, $(this), { rowId: rowid1, colModel: cm[i] }, i);
  13202. } catch (_) {
  13203. tmp = cm[i].edittype === "textarea" ? $(this).text() : $(this).html();
  13204. }
  13205. if (p.autoEncodeOnEdit) { tmp = jgrid.oldDecodePostedData(tmp); }
  13206. if (o.checkOnSubmit === true || o.checkOnUpdate) { o._savedData[nm] = tmp; }
  13207. nm = "#" + jqID(nm);
  13208. switch (cm[i].edittype) {
  13209. case "password":
  13210. case "text":
  13211. case "button":
  13212. case "image":
  13213. case "textarea":
  13214. if (isEmptyString(tmp)) { tmp = ""; }
  13215. $(nm, fmid).val(tmp);
  13216. break;
  13217. case "select":
  13218. var valuesToSelect = tmp.split(",");
  13219. valuesToSelect = $.map(valuesToSelect, function (n) { return $.trim(n); });
  13220. // first of all we try to select options testing the valuesToSelect,
  13221. // we will remove the values from valuesToSelect, which will be found by value
  13222. // In the next step we go through all options once more time and select the options
  13223. // testing there by text. In other words selection by text will be used only for
  13224. // values from valuesToSelect, which not exist as option by value
  13225. $(nm + " option", fmid).each(function () {
  13226. var selOpt = this, $selOpt = $(selOpt), optVal = $.trim($selOpt.val()), iVal;
  13227. if (!cm[i].editoptions.multiple && valuesToSelect[0] === optVal) {
  13228. valuesToSelect.splice(0, 1);
  13229. selOpt.selected = true;
  13230. } else if (cm[i].editoptions.multiple) {
  13231. iVal = $.inArray(optVal, valuesToSelect);
  13232. if (iVal > -1) {
  13233. valuesToSelect.splice(iVal, 1);
  13234. selOpt.selected = true;
  13235. } else {
  13236. selOpt.selected = false;
  13237. }
  13238. } else {
  13239. selOpt.selected = false;
  13240. }
  13241. if (valuesToSelect.length === 0) { return false; }
  13242. });
  13243. if (valuesToSelect.length > 0) {
  13244. $(nm + " option", fmid).each(function () {
  13245. var selOpt = this, $selOpt = $(selOpt), optText = $.trim($selOpt.text()), iVal;
  13246. if (!cm[i].editoptions.multiple && ($.trim(tmp) === optText || valuesToSelect[0] === optText)) {
  13247. valuesToSelect.splice(0, 1);
  13248. selOpt.selected = true;
  13249. } else if (cm[i].editoptions.multiple) {
  13250. iVal = $.inArray(optText, valuesToSelect);
  13251. if (iVal > -1) {
  13252. valuesToSelect.splice(iVal, 1);
  13253. selOpt.selected = true;
  13254. }
  13255. }
  13256. if (valuesToSelect.length === 0) { return false; }
  13257. });
  13258. }
  13259. break;
  13260. case "checkbox":
  13261. tmp = String(tmp);
  13262. // tmp will be set below (in the if-else) to Boolean true or false
  13263. if (cm[i].editoptions && cm[i].editoptions.value) {
  13264. tmp = cm[i].editoptions.value.split(":")[0] === tmp;
  13265. } else {
  13266. tmp = tmp.toLowerCase();
  13267. tmp = tmp.search(/(false|f|0|no|n|off|undefined)/i) < 0 && tmp !== "";
  13268. }
  13269. $(nm, fmid).prop({ checked: tmp, defaultChecked: tmp });
  13270. break;
  13271. case "custom":
  13272. try {
  13273. if (cm[i].editoptions && $.isFunction(cm[i].editoptions.custom_value)) {
  13274. cm[i].editoptions.custom_value.call($t, $(nm, fmid), "set", tmp);
  13275. } else { throw "e1"; }
  13276. } catch (e) {
  13277. if (e === "e1") {
  13278. jgrid.info_dialog.call($t, errcap, "function 'custom_value' " + o.msg.nodefined, o.bClose);
  13279. } else {
  13280. jgrid.info_dialog.call($t, errcap, e.message, o.bClose);
  13281. }
  13282. }
  13283. break;
  13284. }
  13285. cnt++;
  13286. }
  13287. });
  13288. if (cnt > 0) { $("#id_g", frmtb).val(rowid1); }
  13289. }
  13290. function setNullsOrUnformat() {
  13291. var url = o.url || p.editurl;
  13292. $.each(colModel, function (i, cm) {
  13293. var cmName = cm.name;
  13294. if (postdata.hasOwnProperty(cmName)) {
  13295. if (cm.formatter === "date" && (cm.formatoptions == null || cm.formatoptions.sendFormatted !== true)) {
  13296. // TODO: call all other predefined formatters!!! Not only formatter: "date" have the problem.
  13297. // Floating point separator for example
  13298. postdata[cmName] = $.unformat.date.call($t, postdata[cmName], cm);
  13299. }
  13300. if (url !== "clientArray" && cm.editoptions && cm.editoptions.NullIfEmpty === true && postdata[cmName] === "") {
  13301. postdata[cmName] = "null";
  13302. }
  13303. }
  13304. });
  13305. }
  13306. function postIt() {
  13307. var successResult = [true, "", ""], ret = successResult, onClickSubmitResult = {}, opers = p.prmNames, idname, oper, key, selr, i, url, itm, iCol,
  13308. iRow = base.getInd.call($self, rowid),
  13309. tr = iRow === false ? null : $t.rows[iRow],
  13310. retvals = $self.triggerHandler("jqGridAddEditBeforeCheckValues", [postdata, $(frmgr), editOrAdd]);
  13311. if (retvals && typeof retvals === "object") { postdata = retvals; }
  13312. iRow = iRow === false ? -1 : iRow;
  13313. if ($.isFunction(o.beforeCheckValues)) {
  13314. retvals = o.beforeCheckValues.call($t, postdata, $(frmgr), editOrAdd);
  13315. if (retvals && typeof retvals === "object") { postdata = retvals; }
  13316. }
  13317. for (key in postdata) {
  13318. if (postdata.hasOwnProperty(key)) {
  13319. iCol = p.iColByName[key];
  13320. ret = jgrid.checkValues.call($t, postdata[key], key, undefined, undefined, {
  13321. oldValue: rowid === "_empty" ? null : base.getCell.call($self, rowid, iCol),
  13322. newValue: postdata[key],
  13323. cmName: key,
  13324. rowid: rowid,
  13325. cm: colModel[iCol],
  13326. iCol: iCol,
  13327. iRow: iRow,
  13328. tr: tr,
  13329. td: tr == null ? null : tr.cells[iCol],
  13330. mode: rowid === "_empty" ? "addForm" : "editForm"
  13331. });
  13332. if (ret == null || ret === true) { ret = successResult; }
  13333. if (ret[0] === false) { break; }
  13334. }
  13335. }
  13336. setNullsOrUnformat();
  13337. if (ret[0]) {
  13338. onClickSubmitResult = $self.triggerHandler("jqGridAddEditClickSubmit", [o, postdata, editOrAdd]);
  13339. if (onClickSubmitResult === undefined && $.isFunction(o.onclickSubmit)) {
  13340. onClickSubmitResult = o.onclickSubmit.call($t, o, postdata, editOrAdd) || {};
  13341. }
  13342. ret = $self.triggerHandler("jqGridAddEditBeforeSubmit", [postdata, $(frmgr), editOrAdd]);
  13343. if (ret == null || ret === true) { ret = successResult; }
  13344. if (ret[0] && $.isFunction(o.beforeSubmit)) {
  13345. ret = o.beforeSubmit.call($t, postdata, $(frmgr), editOrAdd);
  13346. if (ret == null || ret === true) { ret = successResult; }
  13347. }
  13348. }
  13349. if (ret[0] && !o.processing) {
  13350. o.processing = true;
  13351. $("#sData", frmtb2).addClass(activeClass);
  13352. url = o.url || p.editurl;
  13353. oper = opers.oper;
  13354. idname = url === "clientArray" && p.keyName !== false ? p.keyName : opers.id;
  13355. // we add to pos data array the action - the name is oper
  13356. postdata[oper] = ($.trim(postdata[gridId + "_id"]) === "_empty") ? opers.addoper : opers.editoper;
  13357. if (postdata[oper] !== opers.addoper) {
  13358. postdata[idname] = postdata[gridId + "_id"];
  13359. } else {
  13360. // check to see if we have allredy this field in the form and if yes lieve it
  13361. if (postdata[idname] === undefined) { postdata[idname] = postdata[gridId + "_id"]; }
  13362. }
  13363. delete postdata[gridId + "_id"];
  13364. postdata = $.extend(postdata, o.editData, onClickSubmitResult);
  13365. if (p.treeGrid === true) {
  13366. if (postdata[oper] === opers.addoper) {
  13367. selr = p.selrow;
  13368. var parentIdField = p.treeGridModel === "adjacency" ? p.treeReader.parent_id_field : "parent_id";
  13369. postdata[parentIdField] = selr;
  13370. }
  13371. for (i in p.treeReader) {
  13372. if (p.treeReader.hasOwnProperty(i)) {
  13373. itm = p.treeReader[i];
  13374. if (postdata.hasOwnProperty(itm)) {
  13375. if (postdata[oper] === opers.addoper && i === "parent_id_field") { continue; }
  13376. delete postdata[itm];
  13377. }
  13378. }
  13379. }
  13380. }
  13381. postdata[idname] = jgrid.stripPref(p.idPrefix, postdata[idname]);
  13382. if (p.autoEncodeOnEdit) {
  13383. $.each(postdata, function (n, v) {
  13384. if (!$.isFunction(v)) {
  13385. postdata[n] = jgrid.oldEncodePostedData(v);
  13386. }
  13387. });
  13388. }
  13389. var ajaxOptions = $.extend({
  13390. url: $.isFunction(url) ? url.call($t, postdata[idname], editOrAdd, postdata, o) : url,
  13391. type: $.isFunction(o.mtype) ? o.mtype.call($t, editOrAdd, o, postdata[idname], postdata) : o.mtype,
  13392. //data: $.isFunction(o.serializeEditData) ? o.serializeEditData.call($t,postdata) : postdata,
  13393. data: jgrid.serializeFeedback.call($t,
  13394. $.isFunction(o.serializeEditData) ? o.serializeEditData : p.serializeEditData,
  13395. "jqGridAddEditSerializeEditData",
  13396. postdata),
  13397. complete: function (jqXHR, textStatus) {
  13398. $self.jqGrid("progressBar", { method: "hide", loadtype: o.saveui });
  13399. $("#sData", frmtb2).removeClass(activeClass);
  13400. postdata[idname] = $("#id_g", frmtb).val();
  13401. if ((jqXHR.status >= 300 && jqXHR.status !== 304) || (jqXHR.status === 0 && jqXHR.readyState === 4)) {
  13402. ret[0] = false;
  13403. ret[1] = $self.triggerHandler("jqGridAddEditErrorTextFormat", [jqXHR, editOrAdd]);
  13404. if ($.isFunction(o.errorTextFormat)) {
  13405. ret[1] = o.errorTextFormat.call($t, jqXHR, editOrAdd);
  13406. } else {
  13407. ret[1] = textStatus + " Status: '" + jqXHR.statusText + "'. Error code: " + jqXHR.status;
  13408. }
  13409. } else {
  13410. // data is posted successful
  13411. // execute aftersubmit with the returned data from server
  13412. ret = $self.triggerHandler("jqGridAddEditAfterSubmit", [jqXHR, postdata, editOrAdd]);
  13413. if (ret == null || ret === true) { ret = successResult; }
  13414. if (ret[0] && $.isFunction(o.afterSubmit)) {
  13415. ret = o.afterSubmit.call($t, jqXHR, postdata, editOrAdd);
  13416. if (ret == null || ret === true) { ret = successResult; }
  13417. }
  13418. }
  13419. if (ret[0] === false) {
  13420. $("#FormError>td", frmtb).html(ret[1]);
  13421. $("#FormError", frmtb).show();
  13422. } else {
  13423. if (p.autoEncodeOnEdit) {
  13424. $.each(postdata, function (n, v) {
  13425. postdata[n] = jgrid.oldDecodePostedData(v);
  13426. });
  13427. }
  13428. //o.reloadAfterSubmit = o.reloadAfterSubmit && $t.o.datatype != "local";
  13429. // the action is add
  13430. var reloadGridOptions = [$.extend({}, o.reloadGridOptions || {})];
  13431. if (postdata[oper] === opers.addoper) {
  13432. //id processing
  13433. // user not set the id ret[2]
  13434. if (!ret[2]) { ret[2] = jgrid.randId(); }
  13435. if (postdata[idname] == null || postdata[idname] === "_empty" || postdata[oper] === opers.addoper) {
  13436. postdata[idname] = ret[2];
  13437. } else {
  13438. ret[2] = postdata[idname];
  13439. }
  13440. if (o.reloadAfterSubmit) {
  13441. $self.trigger("reloadGrid", reloadGridOptions);
  13442. } else {
  13443. if (p.treeGrid === true) {
  13444. base.addChildNode.call($self, ret[2], selr, postdata);
  13445. } else {
  13446. base.addRowData.call($self, ret[2], postdata, o.addedrow);
  13447. }
  13448. }
  13449. if (o.closeAfterAdd) {
  13450. if (p.treeGrid !== true) {
  13451. setSelection.call($self, ret[2]);
  13452. }
  13453. hideModal();
  13454. } else if (o.clearAfterAdd) {
  13455. fillData("_empty", frmgr);
  13456. }
  13457. } else {
  13458. // the action is update
  13459. if (o.reloadAfterSubmit) {
  13460. $self.trigger("reloadGrid", reloadGridOptions);
  13461. if (!o.closeAfterEdit) { setTimeout(function () { setSelection.call($self, postdata[idname]); }, 1000); }
  13462. } else {
  13463. if (p.treeGrid === true) {
  13464. base.setTreeRow.call($self, postdata[idname], postdata);
  13465. } else {
  13466. base.setRowData.call($self, postdata[idname], postdata);
  13467. }
  13468. }
  13469. if (o.closeAfterEdit) {
  13470. hideModal();
  13471. }
  13472. }
  13473. if ($.isFunction(o.afterComplete)) {
  13474. var copydata = jqXHR;
  13475. setTimeout(function () {
  13476. $self.triggerHandler("jqGridAddEditAfterComplete", [copydata, postdata, $(frmgr), editOrAdd]);
  13477. o.afterComplete.call($t, copydata, postdata, $(frmgr), editOrAdd);
  13478. copydata = null;
  13479. }, 50);
  13480. }
  13481. if (o.checkOnSubmit || o.checkOnUpdate) {
  13482. $(frmgr).data("disabled", false);
  13483. if (o._savedData[gridId + "_id"] !== "_empty") {
  13484. var key1;
  13485. for (key1 in o._savedData) {
  13486. if (o._savedData.hasOwnProperty(key1) && postdata[key1]) {
  13487. o._savedData[key1] = postdata[key1];
  13488. }
  13489. }
  13490. }
  13491. }
  13492. }
  13493. o.processing = false;
  13494. try {
  13495. $(frmgr).find("input,textarea,select,button,object,*[tabindex]")
  13496. .filter(":input:visible:not(:disabled)")
  13497. .first()
  13498. .focus();
  13499. } catch (ignore) { }
  13500. }
  13501. }, jgrid.ajaxOptions, o.ajaxEditOptions);
  13502. if (!ajaxOptions.url && !o.useDataProxy) {
  13503. if ($.isFunction(p.dataProxy)) {
  13504. o.useDataProxy = true;
  13505. } else {
  13506. ret[0] = false;
  13507. ret[1] += " " + jgrid.errors.nourl;
  13508. }
  13509. }
  13510. if (ret[0]) {
  13511. $self.jqGrid("progressBar", { method: "show", loadtype: o.saveui, htmlcontent: o.savetext });
  13512. if (o.useDataProxy) {
  13513. var dpret = p.dataProxy.call($t, ajaxOptions, "set_" + gridId);
  13514. if (dpret === undefined) {
  13515. dpret = [true, ""];
  13516. }
  13517. if (dpret[0] === false) {
  13518. ret[0] = false;
  13519. ret[1] = dpret[1] || "Error deleting the selected row!";
  13520. } else {
  13521. if (ajaxOptions.data.oper === opers.addoper && o.closeAfterAdd) {
  13522. hideModal();
  13523. }
  13524. if (ajaxOptions.data.oper === opers.editoper && o.closeAfterEdit) {
  13525. hideModal();
  13526. }
  13527. }
  13528. } else {
  13529. if (ajaxOptions.url === "clientArray") {
  13530. o.reloadAfterSubmit = false;
  13531. postdata = ajaxOptions.data;
  13532. ajaxOptions.complete({ status: 200, statusText: "" }, "");
  13533. } else {
  13534. $.ajax(ajaxOptions);
  13535. }
  13536. }
  13537. }
  13538. }
  13539. if (ret[0] === false) {
  13540. $("#FormError>td", frmtb).html(ret[1]);
  13541. $("#FormError", frmtb).show();
  13542. // return;
  13543. }
  13544. }
  13545. function compareData(nObj, oObj) {
  13546. var ret = false, key;
  13547. for (key in nObj) {
  13548. if (nObj.hasOwnProperty(key) && String(nObj[key]) !== String(oObj[key])) {
  13549. ret = true;
  13550. break;
  13551. }
  13552. }
  13553. return ret;
  13554. }
  13555. function checkUpdates() {
  13556. var stat = true;
  13557. $("#FormError", frmtb).hide();
  13558. if (o.checkOnUpdate) {
  13559. postdata = {};
  13560. getFormData();
  13561. diff = compareData(postdata, o._savedData);
  13562. if (diff) {
  13563. $(frmgr).data("disabled", true);
  13564. $(".confirm", themodalSelector).show();
  13565. stat = false;
  13566. }
  13567. }
  13568. return stat;
  13569. }
  13570. function restoreInline() {
  13571. var editingInfo = jgrid.detectRowEditing.call($t, rowid);
  13572. if (editingInfo != null) {
  13573. if (editingInfo.mode === "inlineEditing") {
  13574. base.restoreRow.call($self, rowid);
  13575. } else {
  13576. var savedRowInfo = editingInfo.savedRow, tr = $t.rows[savedRowInfo.id];
  13577. base.restoreCell.call($self, savedRowInfo.id, savedRowInfo.ic);
  13578. // remove highlighting of the cell
  13579. $(tr.cells[savedRowInfo.ic]).removeClass("edit-cell " + highlightClass);
  13580. $(tr).addClass(highlightClass).attr({ "aria-selected": "true", "tabindex": "0" });
  13581. }
  13582. }
  13583. }
  13584. function updateNav(cr, posarr) {
  13585. var totr = posarr[1].length - 1;
  13586. if (cr === 0) {
  13587. $("#pData", frmtb2).addClass(disabledClass);
  13588. } else if (posarr[1][cr - 1] !== undefined && hasOneFromClasses($("#" + jqID(posarr[1][cr - 1])), disabledClass)) {
  13589. $("#pData", frmtb2).addClass(disabledClass);
  13590. } else {
  13591. $("#pData", frmtb2).removeClass(disabledClass);
  13592. }
  13593. if (cr === totr) {
  13594. $("#nData", frmtb2).addClass(disabledClass);
  13595. } else if (posarr[1][cr + 1] !== undefined && hasOneFromClasses($("#" + jqID(posarr[1][cr + 1])), disabledClass)) {
  13596. $("#nData", frmtb2).addClass(disabledClass);
  13597. } else {
  13598. $("#nData", frmtb2).removeClass(disabledClass);
  13599. }
  13600. }
  13601. function getCurrPos() {
  13602. var rowsInGrid = base.getDataIDs.call($self),
  13603. selrow = $("#id_g", frmtb).val(),
  13604. pos = $.inArray(selrow, rowsInGrid);
  13605. return [pos, rowsInGrid];
  13606. }
  13607. var dh = isNaN(o.dataheight) ? o.dataheight : o.dataheight + "px",
  13608. dw = isNaN(o.datawidth) ? o.datawidth : o.datawidth + "px",
  13609. frm = $("<form name='FormPost' id='" + frmgrId + "' class='FormGrid' onSubmit='return false;' style='width:" + dw + ";overflow:auto;position:relative;height:" + dh + ";'></form>").data("disabled", false),
  13610. tbl = $("<table id='" + frmtborg + "' class='EditTable'><tbody></tbody></table>");
  13611. $(colModel).each(function () {
  13612. var fmto = this.formoptions;
  13613. maxCols = Math.max(maxCols, fmto ? fmto.colpos || 0 : 0);
  13614. maxRows = Math.max(maxRows, fmto ? fmto.rowpos || 0 : 0);
  13615. });
  13616. $(frm).append(tbl);
  13617. var flr = $("<tr id='FormError' style='display:none'><td class='" + errorClass + "' colspan='" + (maxCols * 2) + "'>&#160;</td></tr>");
  13618. flr[0].rp = 0;
  13619. $(tbl).append(flr);
  13620. //topinfo
  13621. flr = $("<tr style='display:none' class='tinfo'><td class='topinfo' colspan='" + (maxCols * 2) + "'>" + (o.topinfo || "&#160;") + "</td></tr>");
  13622. flr[0].rp = 0;
  13623. $(tbl).append(flr);
  13624. if (!editFeedback("beforeInitData", frm, editOrAdd)) { return; }
  13625. restoreInline();
  13626. // set the id.
  13627. // use carefull only to change here colproperties.
  13628. // create data
  13629. var rtlb = p.direction === "rtl" ? true : false,
  13630. bp = rtlb ? "nData" : "pData",
  13631. bn = rtlb ? "pData" : "nData";
  13632. createData(rowid, tbl, maxCols);
  13633. // buttons at footer
  13634. var bP = builderFmButon.call($t, bp, "", mergeCssClasses(commonIconClass, o.prevIcon), "", "left"),
  13635. bN = builderFmButon.call($t, bn, "", mergeCssClasses(commonIconClass, o.nextIcon), "", "right"),
  13636. bS = builderFmButon.call($t, "sData", o.bSubmit),
  13637. bC = builderFmButon.call($t, "cData", o.bCancel),
  13638. bt = "<div class='" + getGuiStyles.call($t, "dialog.footer") + "'><table class='EditTable' id='" + frmtborg + "_2'><tbody><tr><td colspan='2'><hr class='" +
  13639. getGuiStyles.call($t, "dialog.hr") + "' style='margin:1px'/></td></tr><tr id='Act_Buttons'><td class='navButton navButton-" + p.direction + "'>" + (rtlb ? bN + bP : bP + bN) + "</td><td class='EditButton EditButton-" + p.direction + "'>" + bS + "&#160;" + bC + "</td></tr>";
  13640. bt += "<tr style='display:none' class='binfo'><td class='bottominfo' colspan='2'>" + (o.bottominfo || "&#160;") + "</td></tr>";
  13641. bt += "</tbody></table></div>";
  13642. if (maxRows > 0) {
  13643. var sd = [];
  13644. $.each($(tbl)[0].rows, function (i, r) {
  13645. sd[i] = r;
  13646. });
  13647. sd.sort(function (a, b) {
  13648. if (a.rp > b.rp) { return 1; }
  13649. if (a.rp < b.rp) { return -1; }
  13650. return 0;
  13651. });
  13652. $.each(sd, function (index, row) {
  13653. $("tbody", tbl).append(row);
  13654. });
  13655. }
  13656. o.gbox = gboxSelector;
  13657. var cle = false;
  13658. if (o.closeOnEscape === true) {
  13659. o.closeOnEscape = false;
  13660. cle = true;
  13661. }
  13662. var tms = $("<div></div>").append($("<div class='" + getGuiStyles.call($t, "dialog.body") + "'></div>").append(frm)).append(bt);
  13663. jgrid.createModal.call($t, ids, tms, o, p.gView, $(gboxSelector)[0]);
  13664. // TODO: remove the call of jgrid.bindEv and probably call of opt.custom_value from createData
  13665. // and place the calls here AFTER the form are placed on the HTML page
  13666. if (o.topinfo) { $(".tinfo", frmtb).show(); }
  13667. if (o.bottominfo) { $(".binfo", frmtb2).show(); }
  13668. tms = null;
  13669. bt = null;
  13670. $(themodalSelector).keydown(function (e) {
  13671. var wTagName = (e.target.tagName || "").toUpperCase(), $focused, idFocused;
  13672. if ($(frmgr).data("disabled") === true) { return false; }//??
  13673. if (e.which === 13) {
  13674. if (wTagName !== "TEXTAREA") {
  13675. $focused = $(frmtb2).find(":focus");
  13676. idFocused = $focused.attr("id");
  13677. if ($focused.length > 0 && $.inArray(idFocused, ["pData", "nData", "cData"]) >= 0) {
  13678. $focused.trigger("click");
  13679. return false;
  13680. }
  13681. if (o.savekey[0] === true && o.savekey[1] === 13) {
  13682. $("#sData", frmtb2).trigger("click");
  13683. return false;
  13684. }
  13685. }
  13686. }
  13687. if (o.savekey[0] === true && e.which === o.savekey[1]) { // save
  13688. if (wTagName !== "TEXTAREA") {
  13689. $("#sData", frmtb2).trigger("click");
  13690. return false;
  13691. }
  13692. }
  13693. if (e.which === 27) {
  13694. if (!checkUpdates()) { return false; }
  13695. if (cle) {
  13696. hideModal();
  13697. }
  13698. return false;
  13699. }
  13700. if (o.navkeys[0] === true) {
  13701. if ($("#id_g", frmtb).val() === "_empty") { return true; }
  13702. if (e.which === o.navkeys[1]) { //up
  13703. $("#pData", frmtb2).trigger("click");
  13704. return false;
  13705. }
  13706. if (e.which === o.navkeys[2]) { //down
  13707. $("#nData", frmtb2).trigger("click");
  13708. return false;
  13709. }
  13710. }
  13711. });
  13712. if (o.checkOnUpdate) {
  13713. $("a.ui-jqdialog-titlebar-close span", themodalSelector).removeClass("jqmClose");
  13714. $("a.ui-jqdialog-titlebar-close", themodalSelector).off("click")
  13715. .click(function () {
  13716. if (!checkUpdates()) {
  13717. return false;
  13718. }
  13719. hideModal();
  13720. return false;
  13721. });
  13722. }
  13723. addFormIcon($("#sData", frmtb2), o.saveicon, commonIconClass);
  13724. addFormIcon($("#cData", frmtb2), o.closeicon, commonIconClass);
  13725. if (o.checkOnSubmit || o.checkOnUpdate) {
  13726. bS = builderFmButon.call($t, "sNew", o.bYes);
  13727. bN = builderFmButon.call($t, "nNew", o.bNo);
  13728. bC = builderFmButon.call($t, "cNew", o.bExit);
  13729. var zI = o.zIndex || 999;
  13730. zI++;
  13731. $("<div class='" + o.overlayClass + " jqgrid-overlay confirm' style='z-index:" + zI + ";display:none;'>&#160;</div><div class='" + getGuiStyles.call($t, "dialog.content", "confirm ui-jqconfirm") + "' style='z-index:" + (zI + 1) + "'>" + o.saveData + "<br/><br/>" + bS + bN + bC + "</div>").insertAfter(frmgr);
  13732. $("#sNew", themodalSelector).click(function () {
  13733. // if the form will be hidden at the first usage and it will be shown at the next usage
  13734. // then the execution context click handler and all other functions like postIt()
  13735. // will contains the variables (like rowid, postdata and so on) from THE FIRST call
  13736. // of editGridRow. One should be very careful in the code of postIt()
  13737. postIt();
  13738. $(frmgr).data("disabled", false);
  13739. $(".confirm", themodalSelector).hide();
  13740. return false;
  13741. });
  13742. $("#nNew", themodalSelector).click(function () {
  13743. $(".confirm", themodalSelector).hide();
  13744. $(frmgr).data("disabled", false);
  13745. setTimeout(function () {
  13746. $(frmgr).find("input,textarea,select,button,object,*[tabindex]")
  13747. .filter(":input:visible:not(:disabled)")
  13748. .first()
  13749. .focus();
  13750. }, 0);
  13751. return false;
  13752. });
  13753. $("#cNew", themodalSelector).click(function () {
  13754. // if the form will be hidden at the first usage and it will be shown at the next usage
  13755. // then the execution context click handler and all other functions like postIt()
  13756. // will contains the variables (like o) from THE FIRST call
  13757. $(".confirm", themodalSelector).hide();
  13758. $(frmgr).data("disabled", false);
  13759. hideModal();
  13760. return false;
  13761. });
  13762. }
  13763. // here initform - only once
  13764. editFeedback("onInitializeForm", $(frmgr), editOrAdd);
  13765. if (rowid === "_empty" || !o.viewPagerButtons) {
  13766. $("#pData,#nData", frmtb2).hide();
  13767. } else {
  13768. $("#pData,#nData", frmtb2).show();
  13769. }
  13770. editFeedback("beforeShowForm", $(frmgr), editOrAdd);
  13771. $(themodalSelector).data("onClose", o.onClose);
  13772. jgrid.viewModal.call($t, themodalSelector, {
  13773. gbox: gboxSelector,
  13774. jqm: o.jqModal,
  13775. overlay: o.overlay,
  13776. modal: o.modal,
  13777. overlayClass: o.overlayClass,
  13778. toTop: o.toTop,
  13779. onHide: function (h) {
  13780. h.w.remove();
  13781. if (h.o) { h.o.remove(); }
  13782. }
  13783. });
  13784. if (!closeovrl) {
  13785. $("." + jqID(o.overlayClass)).click(function () {
  13786. if (!checkUpdates()) { return false; }
  13787. hideModal();
  13788. return false;
  13789. });
  13790. }
  13791. $(".fm-button", themodalSelector).hover(
  13792. function () { $(this).addClass(hoverClasses); },
  13793. function () { $(this).removeClass(hoverClasses); }
  13794. );
  13795. $("#sData", frmtb2).click(function () {
  13796. postdata = {};
  13797. $("#FormError", frmtb).hide();
  13798. // all depend on ret array
  13799. //ret[0] - succes
  13800. //ret[1] - msg if not succes
  13801. //ret[2] - the id that will be set if reload after submit false
  13802. getFormData();
  13803. if (postdata[gridId + "_id"] === "_empty") {
  13804. postIt();
  13805. } else if (o.checkOnSubmit === true) {
  13806. diff = compareData(postdata, o._savedData);
  13807. if (diff) {
  13808. $(frmgr).data("disabled", true);
  13809. $(".confirm", themodalSelector).show();
  13810. } else {
  13811. postIt();
  13812. }
  13813. } else {
  13814. postIt();
  13815. }
  13816. return false;
  13817. });
  13818. $("#cData", frmtb2).click(function () {
  13819. if (!checkUpdates()) { return false; }
  13820. hideModal();
  13821. return false;
  13822. });
  13823. $("#nData", frmtb2).click(function () {
  13824. if (!checkUpdates()) { return false; }
  13825. $("#FormError", frmtb).hide();
  13826. var npos = getCurrPos();
  13827. npos[0] = parseInt(npos[0], 10);
  13828. if (npos[0] !== -1 && npos[1][npos[0] + 1]) {
  13829. if (!editFeedback("onclickPgButtons", "next", $(frmgr), npos[1][npos[0]])) { return false; }
  13830. fillData(npos[1][npos[0] + 1], frmgr);
  13831. setSelection.call($self, npos[1][npos[0] + 1]);
  13832. editFeedback("afterclickPgButtons", "next", $(frmgr), npos[1][npos[0] + 1]);
  13833. updateNav(npos[0] + 1, npos);
  13834. }
  13835. return false;
  13836. });
  13837. $("#pData", frmtb2).click(function () {
  13838. if (!checkUpdates()) { return false; }
  13839. $("#FormError", frmtb).hide();
  13840. var ppos = getCurrPos();
  13841. if (ppos[0] !== -1 && ppos[1][ppos[0] - 1]) {
  13842. if (!editFeedback("onclickPgButtons", "prev", $(frmgr), ppos[1][ppos[0]])) { return false; }
  13843. if (hasOneFromClasses($("#" + jqID(ppos[1][ppos[0] - 1])), disabledClass)) { return false; }
  13844. fillData(ppos[1][ppos[0] - 1], frmgr);
  13845. setSelection.call($self, ppos[1][ppos[0] - 1]);
  13846. editFeedback("afterclickPgButtons", "prev", $(frmgr), ppos[1][ppos[0] - 1]);
  13847. updateNav(ppos[0] - 1, ppos);
  13848. }
  13849. return false;
  13850. });
  13851. editFeedback("afterShowForm", $(frmgr), editOrAdd);
  13852. var posInit = getCurrPos();
  13853. updateNav(posInit[0], posInit);
  13854. });
  13855. },
  13856. viewGridRow: function (rowid, oMuligrid) {
  13857. return this.each(function () {
  13858. var $t = this, $self = $($t), p = $t.p;
  13859. if (!$t.grid || p == null || !rowid) { return; }
  13860. // make new copy of the options oMuligrid and use it for ONE specific grid.
  13861. // p.formViewing can contains grid specific options
  13862. // we will don't modify the input options oMuligrid
  13863. var gridId = p.id,
  13864. o = $.extend(true,
  13865. {
  13866. top: 0,
  13867. left: 0,
  13868. width: 0,
  13869. datawidth: "auto",
  13870. height: "auto",
  13871. dataheight: "auto",
  13872. //modal: false,
  13873. //toTop : false,
  13874. //overlay: 30,
  13875. drag: true,
  13876. resize: true,
  13877. //jqModal: true,
  13878. closeOnEscape: false,
  13879. labelswidth: "", //"30%",
  13880. navkeys: [false, 38, 40],
  13881. onClose: null,
  13882. beforeShowForm: null,
  13883. beforeInitData: null,
  13884. viewPagerButtons: true,
  13885. removemodal: true
  13886. },
  13887. base.getGridRes.call($self, "view"),
  13888. jgrid.view || {},
  13889. p.formViewing || {},
  13890. oMuligrid || {});
  13891. var frmgr = "#ViewGrid_" + jqID(gridId), frmtb = "#ViewTbl_" + jqID(gridId), frmtb2 = frmtb + "_2",
  13892. frmgrId = "ViewGrid_" + gridId, frmtbId = "ViewTbl_" + gridId, commonIconClass = o.commonIconClass,
  13893. ids = { themodal: "viewmod" + gridId, modalhead: "viewhd" + gridId, modalcontent: "viewcnt" + gridId, resizeAlso: frmgrId },
  13894. themodalSelector = "#" + jqID(ids.themodal), gboxSelector = p.gBox, colModel = p.colModel,
  13895. maxCols = 1, maxRows = 0,
  13896. viewFeedback = function () {
  13897. var args = $.makeArray(arguments);
  13898. args.unshift("");
  13899. args.unshift("View");
  13900. args.unshift(o);
  13901. return jgridFeedback.apply($t, args);
  13902. },
  13903. hideModal = function () {
  13904. jgrid.hideModal(themodalSelector, {
  13905. gb: gboxSelector,
  13906. jqm: o.jqModal,
  13907. onClose: o.onClose,
  13908. removemodal: o.removemodal
  13909. });
  13910. },
  13911. hoverClasses = getGuiStateStyles.call($t, "hover"),
  13912. disabledClass = getGuiStateStyles.call($t, "disabled");
  13913. function focusaref() { //Sfari 3 issues
  13914. if (o.closeOnEscape === true || o.navkeys[0] === true) {
  13915. setTimeout(function () { $("#cData").focus(); }, 0);
  13916. }
  13917. }
  13918. function createData(rowid1, tb, maxcols) {
  13919. var nm, hc, $trdata, cnt = 0, tmp, retpos = [], ind = base.getInd.call($self, rowid1), i,
  13920. viewDataClasses = getGuiStyles.call($t, "dialog.viewData"), $tb = $(tb),
  13921. viewLabelClasses = getGuiStyles.call($t, "dialog.viewLabel"),
  13922. labelsWidth = String(o.labelswidth) + (!o.labelswidth || isNaN(o.labelswidth) ? "" : "px"),
  13923. tdtmpl = "<td class='" +
  13924. getGuiStyles.call($t, "dialog.viewCellLabel", "CaptionTD form-view-label") +
  13925. (labelsWidth ? "' style='width:" + labelsWidth + ";" : "") +
  13926. "'>&#160;</td><td class='" +
  13927. getGuiStyles.call($t, "dialog.viewCellData", "DataTD form-view-data") +
  13928. "'>&#160;</td>",
  13929. tmpl = "", fmtnum = ["integer", "number", "currency"], max1 = 0, max2 = 0, maxw, setme, viewfld;
  13930. for (i = 0; i < maxcols; i++) {
  13931. tmpl += tdtmpl;
  13932. }
  13933. // find max number align right with property formatter
  13934. $(colModel).each(function () {
  13935. var cm = this;
  13936. if (cm.editrules && cm.editrules.edithidden === true) {
  13937. hc = false;
  13938. } else {
  13939. hc = cm.hidden === true ? true : false;
  13940. }
  13941. if (!hc && cm.align === "right") {
  13942. if (cm.formatter && $.inArray(cm.formatter, fmtnum) !== -1) {
  13943. max1 = Math.max(max1, parseInt(cm.width, 10));
  13944. } else {
  13945. max2 = Math.max(max2, parseInt(cm.width, 10));
  13946. }
  13947. }
  13948. });
  13949. maxw = max1 !== 0 ? max1 : max2 !== 0 ? max2 : 0;
  13950. $(colModel).each(function (iCol) {
  13951. var cm = this;
  13952. nm = cm.name;
  13953. setme = false;
  13954. // hidden fields are included in the form
  13955. if (cm.editrules && cm.editrules.edithidden === true) {
  13956. hc = false;
  13957. } else {
  13958. hc = cm.hidden === true ? true : false;
  13959. }
  13960. viewfld = (typeof cm.viewable !== "boolean") ? true : cm.viewable;
  13961. if (nm !== "cb" && nm !== "subgrid" && nm !== "rn" && viewfld) {
  13962. tmp = ind === false ? "" : jgrid.getDataFieldOfCell.call($t, $t.rows[ind], iCol).html();
  13963. setme = cm.align === "right" && maxw !== 0 ? true : false;
  13964. var frmopt = $.extend({}, { rowabove: false, rowcontent: "" }, cm.formoptions || {}),
  13965. rp = parseInt(frmopt.rowpos, 10) || cnt + 1,
  13966. cp = parseInt((parseInt(frmopt.colpos, 10) || 1) * 2, 10);
  13967. if (frmopt.rowabove) {
  13968. var newdata = $("<tr><td class='contentinfo' colspan='" + (maxcols * 2) + "'>" + frmopt.rowcontent + "</td></tr>");
  13969. $tb.append(newdata);
  13970. newdata[0].rp = rp;
  13971. }
  13972. $trdata = $tb.find("tr[data-rowpos=" + rp + "]");
  13973. if ($trdata.length === 0) {
  13974. $trdata = $("<tr data-rowpos='" + rp + "'></tr>")
  13975. .addClass("FormData")
  13976. .attr("id", "trv_" + nm);
  13977. $trdata.append(tmpl);
  13978. $tb.append($trdata);
  13979. $trdata[0].rp = rp;
  13980. }
  13981. var labelText = (frmopt.label === undefined ? p.colNames[iCol] : frmopt.label),
  13982. $data = $("td:eq(" + (cp - 1) + ")", $trdata[0]),
  13983. $label = $("td:eq(" + (cp - 2) + ")", $trdata[0]);
  13984. $label.html("<label for='" + nm + "'" +
  13985. (viewLabelClasses ? " class='" + viewLabelClasses + "'>" : ">") +
  13986. (labelText || "&nbsp;") + "</label>");
  13987. $data[isEmptyString($data.html()) ? "html" : "append"]("<span id='" + nm + "'" +
  13988. (viewDataClasses ? " class='" + viewDataClasses + "'>" : ">") +
  13989. (tmp || "&nbsp;") + "</span>").attr("id", "v_" + nm);
  13990. if (setme) {
  13991. $("td:eq(" + (cp - 1) + ") span", $trdata[0]).css({ "text-align": "right", width: maxw + "px" });
  13992. }
  13993. if (hc) {
  13994. $label.add($data).css("visibility", "hidden");
  13995. }
  13996. retpos[cnt] = iCol;
  13997. cnt++;
  13998. }
  13999. });
  14000. hideRowsWithoutVissibleCells($tb);
  14001. if (cnt > 0) {
  14002. var idrow = $("<tr class='FormData' style='display:none'><td class='CaptionTD'>&#160;</td><td colspan='" + (maxcols * 2 - 1) + "' class='DataTD'><input class='FormElement' id='id_g' type='text' name='id' value='" + rowid1 + "'/></td></tr>");
  14003. idrow[0].rp = cnt + 99;
  14004. $tb.append(idrow);
  14005. }
  14006. return retpos;
  14007. }
  14008. function fillData(rowid1) {
  14009. var nm, cnt = 0, trv = base.getInd.call($self, rowid1, true), cm;
  14010. if (!trv) { return; }
  14011. $("td", trv).each(function (i) {
  14012. cm = colModel[i];
  14013. nm = cm.name;
  14014. if (nm !== "cb" && nm !== "subgrid" && nm !== "rn") {
  14015. nm = jqID("v_" + nm);
  14016. $("#" + nm + " span", frmtb).html(jgrid.getDataFieldOfCell.call($t, trv, i).html());
  14017. cnt++;
  14018. }
  14019. });
  14020. //hideRowsWithoutVissibleCells($(frmtb));
  14021. if (cnt > 0) { $("#id_g", frmtb).val(rowid1); }
  14022. }
  14023. function updateNav(cr, posarr) {
  14024. var totr = posarr[1].length - 1;
  14025. if (cr === 0) {
  14026. $("#pData", frmtb2).addClass(disabledClass);
  14027. } else if (posarr[1][cr - 1] !== undefined && hasOneFromClasses($("#" + jqID(posarr[1][cr - 1])), disabledClass)) {
  14028. $("#pData", frmtb2).addClass(disabledClass);
  14029. } else {
  14030. $("#pData", frmtb2).removeClass(disabledClass);
  14031. }
  14032. if (cr === totr) {
  14033. $("#nData", frmtb2).addClass(disabledClass);
  14034. } else if (posarr[1][cr + 1] !== undefined && hasOneFromClasses($("#" + jqID(posarr[1][cr + 1])), disabledClass)) {
  14035. $("#nData", frmtb2).addClass(disabledClass);
  14036. } else {
  14037. $("#nData", frmtb2).removeClass(disabledClass);
  14038. }
  14039. }
  14040. function getCurrPos() {
  14041. var rowsInGrid = base.getDataIDs.call($self),
  14042. selrow = $("#id_g", frmtb).val(),
  14043. pos = $.inArray(selrow, rowsInGrid);
  14044. return [pos, rowsInGrid];
  14045. }
  14046. var dh = isNaN(o.dataheight) ? o.dataheight : o.dataheight + "px",
  14047. dw = isNaN(o.datawidth) ? o.datawidth : o.datawidth + "px",
  14048. frmDiv = $("<div class='" + getGuiStyles.call($t, "dialog.body") + "'><form name='FormPost' id='" + frmgrId +
  14049. "' class='FormGrid' style='width:" + dw + ";overflow:auto;position:relative;height:" + dh + ";'></form></div>"),
  14050. frm = frmDiv.children("form.FormGrid"),
  14051. tbl = $("<table id='" + frmtbId +
  14052. "' class='EditTable'><tbody></tbody></table>");
  14053. $(themodalSelector).remove();
  14054. $(colModel).each(function () {
  14055. var fmto = this.formoptions;
  14056. maxCols = Math.max(maxCols, fmto ? fmto.colpos || 0 : 0);
  14057. maxRows = Math.max(maxRows, fmto ? fmto.rowpos || 0 : 0);
  14058. });
  14059. // set the id.
  14060. frm.append(tbl);
  14061. if (!viewFeedback("beforeInitData", frm)) { return; }
  14062. createData(rowid, tbl, maxCols);
  14063. var rtlb = p.direction === "rtl" ? true : false,
  14064. bp = rtlb ? "nData" : "pData",
  14065. bn = rtlb ? "pData" : "nData",
  14066. // buttons at footer
  14067. bP = builderFmButon.call($t, bp, "", mergeCssClasses(commonIconClass, o.prevIcon), "", "left"),
  14068. bN = builderFmButon.call($t, bn, "", mergeCssClasses(commonIconClass, o.nextIcon), "", "right"),
  14069. bC = builderFmButon.call($t, "cData", o.bClose);
  14070. if (maxRows > 0) {
  14071. var sd = [];
  14072. $.each($(tbl)[0].rows, function (i, r) {
  14073. sd[i] = r;
  14074. });
  14075. sd.sort(function (a, b) {
  14076. if (a.rp > b.rp) { return 1; }
  14077. if (a.rp < b.rp) { return -1; }
  14078. return 0;
  14079. });
  14080. $.each(sd, function (index, row) {
  14081. $("tbody", tbl).append(row);
  14082. });
  14083. }
  14084. o.gbox = gboxSelector;
  14085. var bt = $("<div></div>").append(frmDiv).append("<div class='" + getGuiStyles.call($t, "dialog.footer") + "'><table border='0' class='EditTable' id='" + frmtbId + "_2'><tbody><tr id='Act_Buttons'><td class='navButton navButton-" + p.direction + "' width='" + (o.labelswidth || "auto") + "'>" + (rtlb ? bN + bP : bP + bN) + "</td><td class='EditButton EditButton-" + p.direction + "'>" + bC + "</td></tr></tbody></table></div>");
  14086. jgrid.createModal.call($t, ids, bt, o, p.gView, $(p.gView)[0]);
  14087. if (!o.viewPagerButtons) { $("#pData, #nData", frmtb2).hide(); }
  14088. bt = null;
  14089. $(themodalSelector).keydown(function (e) {
  14090. var $focused, idFocused;
  14091. if ($(frmgr).data("disabled") === true) { return false; }//??
  14092. if (e.which === 13) {
  14093. $focused = $(frmtb2).find(":focus");
  14094. idFocused = $focused.attr("id");
  14095. if ($focused.length > 0 && $.inArray(idFocused, ["pData", "nData", "cData"]) >= 0) {
  14096. $focused.trigger("click");
  14097. return false;
  14098. }
  14099. }
  14100. if (e.which === 27) {
  14101. if (o.closeOnEscape) {
  14102. hideModal();
  14103. }
  14104. return false;
  14105. }
  14106. if (o.navkeys[0] === true) {
  14107. if (e.which === o.navkeys[1]) { //up
  14108. $("#pData", frmtb2).trigger("click");
  14109. return false;
  14110. }
  14111. if (e.which === o.navkeys[2]) { //down
  14112. $("#nData", frmtb2).trigger("click");
  14113. return false;
  14114. }
  14115. }
  14116. });
  14117. addFormIcon($("#cData", frmtb2), o.closeicon, commonIconClass);
  14118. viewFeedback("beforeShowForm", $(frmgr));
  14119. jgrid.viewModal.call($t, themodalSelector, {
  14120. gbox: gboxSelector,
  14121. jqm: o.jqModal,
  14122. overlay: o.overlay,
  14123. toTop: o.toTop,
  14124. modal: o.modal,
  14125. onHide: function (h) {
  14126. h.w.remove();
  14127. if (h.o) { h.o.remove(); }
  14128. }
  14129. });
  14130. $(".fm-button:not(." + disabledClass.split(" ").join(".") + ")", frmtb2).hover(
  14131. function () { $(this).addClass(hoverClasses); },
  14132. function () { $(this).removeClass(hoverClasses); }
  14133. );
  14134. focusaref();
  14135. $("#cData", frmtb2).click(function () {
  14136. hideModal();
  14137. return false;
  14138. });
  14139. $("#nData", frmtb2).click(function () {
  14140. $("#FormError", frmtb).hide();
  14141. var npos = getCurrPos();
  14142. npos[0] = parseInt(npos[0], 10);
  14143. if (npos[0] !== -1 && npos[1][npos[0] + 1]) {
  14144. if (!viewFeedback("onclickPgButtons", "next", $(frmgr), npos[1][npos[0]])) { return false; }
  14145. fillData(npos[1][npos[0] + 1]);
  14146. base.setSelection.call($self, npos[1][npos[0] + 1]);
  14147. viewFeedback("afterclickPgButtons", "next", $(frmgr), npos[1][npos[0] + 1]);
  14148. updateNav(npos[0] + 1, npos);
  14149. }
  14150. focusaref();
  14151. return false;
  14152. });
  14153. $("#pData", frmtb2).click(function () {
  14154. $("#FormError", frmtb).hide();
  14155. var ppos = getCurrPos();
  14156. if (ppos[0] !== -1 && ppos[1][ppos[0] - 1]) {
  14157. if (!viewFeedback("onclickPgButtons", "prev", $(frmgr), ppos[1][ppos[0]])) { return false; }
  14158. fillData(ppos[1][ppos[0] - 1]);
  14159. base.setSelection.call($self, ppos[1][ppos[0] - 1]);
  14160. viewFeedback("afterclickPgButtons", "prev", $(frmgr), ppos[1][ppos[0] - 1]);
  14161. updateNav(ppos[0] - 1, ppos);
  14162. }
  14163. focusaref();
  14164. return false;
  14165. });
  14166. var posInit = getCurrPos();
  14167. updateNav(posInit[0], posInit);
  14168. });
  14169. },
  14170. delGridRow: function (rowids, oMuligrid) {
  14171. return this.each(function () {
  14172. var $t = this, p = $t.p, $self = $($t);
  14173. if (!$t.grid || p == null || !rowids) { return; }
  14174. // make new copy of the options oMuligrid and use it for ONE specific grid.
  14175. // p.formDeleting can contains grid specific options
  14176. // we will don't modify the input options oMuligrid
  14177. var gridId = p.id,
  14178. o = $.extend(true,
  14179. {
  14180. top: 0,
  14181. left: 0,
  14182. width: 240,
  14183. removemodal: true,
  14184. height: "auto",
  14185. dataheight: "auto",
  14186. datawidth: "auto",
  14187. //modal: false,
  14188. //toTop: false,
  14189. //overlay: 30,
  14190. drag: true,
  14191. resize: true,
  14192. url: "",
  14193. mtype: "POST",
  14194. reloadAfterSubmit: true,
  14195. beforeShowForm: null,
  14196. beforeInitData: null,
  14197. afterShowForm: null,
  14198. beforeSubmit: null,
  14199. onclickSubmit: null,
  14200. afterSubmit: null,
  14201. //jqModal : true,
  14202. closeOnEscape: false,
  14203. delData: {},
  14204. idSeparator: ",",
  14205. onClose: null,
  14206. ajaxDelOptions: {},
  14207. processing: false,
  14208. serializeDelData: null,
  14209. useDataProxy: false,
  14210. delui: "disable", // "enable", "enable" or "block"
  14211. deltext: base.getGridRes.call($self, "defaults.deltext") || "Deleting..."
  14212. },
  14213. base.getGridRes.call($self, "del"),
  14214. jgrid.del || {},
  14215. p.formDeleting || {},
  14216. oMuligrid || {});
  14217. var dtblId = "DelTbl_" + gridId, dtbl = "#DelTbl_" + jqID(gridId), postd, idname, opers, oper,
  14218. ids = { themodal: "delmod" + gridId, modalhead: "delhd" + gridId, modalcontent: "delcnt" + gridId, resizeAlso: dtblId },
  14219. themodalSelector = "#" + jqID(ids.themodal), gboxSelector = p.gBox, commonIconClass = o.commonIconClass,
  14220. deleteFeedback = function () {
  14221. var args = $.makeArray(arguments);
  14222. args.unshift("");
  14223. args.unshift("Delete");
  14224. args.unshift(o);
  14225. return jgridFeedback.apply($t, args);
  14226. },
  14227. hoverClasses = getGuiStateStyles.call($t, "hover"),
  14228. activeClass = getGuiStateStyles.call($t, "active"),
  14229. errorClass = getGuiStateStyles.call($t, "error");
  14230. if (!$.isArray(rowids)) { rowids = [String(rowids)]; }
  14231. if ($(themodalSelector)[0] !== undefined) {
  14232. if (!deleteFeedback("beforeInitData", $(dtbl))) { return; }
  14233. $("#DelData>td", dtbl).text(rowids.join(o.idSeparator)).data("rowids", rowids);
  14234. $("#DelError", dtbl).hide();
  14235. if (o.processing === true) {
  14236. o.processing = false;
  14237. $("#dData", dtbl).removeClass(activeClass);
  14238. }
  14239. deleteFeedback("beforeShowForm", $(dtbl));
  14240. jgrid.viewModal.call($t, themodalSelector, {
  14241. gbox: gboxSelector,
  14242. jqm: o.jqModal,
  14243. jqM: false,
  14244. overlay: o.overlay,
  14245. toTop: o.toTop,
  14246. modal: o.modal
  14247. });
  14248. deleteFeedback("afterShowForm", $(dtbl));
  14249. } else {
  14250. var dh = isNaN(o.dataheight) ? o.dataheight : o.dataheight + "px",
  14251. dw = isNaN(o.datawidth) ? o.datawidth : o.datawidth + "px",
  14252. tbl = "<div class='" + getGuiStyles.call($t, "dialog.body") + "'><div id='" + dtblId + "' class='formdata' style='width:" + dw + ";overflow:auto;position:relative;height:" + dh + ";'>";
  14253. tbl += "<table class='DelTable'><tbody>";
  14254. // error data
  14255. tbl += "<tr id='DelError' style='display:none'><td class='" + errorClass + "'></td></tr>";
  14256. tbl += "<tr id='DelData' style='display:none'><td >" + rowids.join(o.idSeparator) + "</td></tr>";
  14257. tbl += "<tr><td class='delmsg'>" + o.msg + "</td></tr>";
  14258. // buttons at footer
  14259. tbl += "</tbody></table></div></div>";
  14260. var bS = builderFmButon.call($t, "dData", o.bSubmit),
  14261. bC = builderFmButon.call($t, "eData", o.bCancel);
  14262. tbl += "<div class='" + getGuiStyles.call($t, "dialog.footer") + "'><table class='EditTable' id='" +
  14263. dtblId + "_2'><tbody><tr><td><hr class='" +
  14264. getGuiStyles.call($t, "dialog.hr") + "' style='margin:1px'/></td></tr><tr><td class='DelButton EditButton EditButton-" +
  14265. p.direction + "'>" + bS + "&#160;" + bC + "</td></tr></tbody></table></div>";
  14266. o.gbox = gboxSelector;
  14267. jgrid.createModal.call($t, ids, tbl, o, p.gView, $(p.gView)[0]);
  14268. $("#DelData>td", dtbl).data("rowids", rowids);
  14269. if (!deleteFeedback("beforeInitData", $(tbl))) { return; }
  14270. $(".fm-button", dtbl + "_2").hover(
  14271. function () { $(this).addClass(hoverClasses); },
  14272. function () { $(this).removeClass(hoverClasses); }
  14273. );
  14274. addFormIcon($("#dData", dtbl + "_2"), o.delicon, commonIconClass);
  14275. addFormIcon($("#eData", dtbl + "_2"), o.cancelicon, commonIconClass);
  14276. $("#dData", dtbl + "_2").click(function () {
  14277. var ret = [true, ""], pk, $delData = $("#DelData>td", dtbl),
  14278. postdata = $delData.text(), //the pair is name=val1,val2,...
  14279. formRowIds = $delData.data("rowids"),
  14280. cs = {};
  14281. if ($.isFunction(o.onclickSubmit)) { cs = o.onclickSubmit.call($t, o, postdata, formRowIds) || {}; }
  14282. if ($.isFunction(o.beforeSubmit)) { ret = o.beforeSubmit.call($t, postdata, formRowIds) || ret; }
  14283. if (ret[0] && !o.processing) {
  14284. o.processing = true;
  14285. opers = p.prmNames;
  14286. postd = $.extend({}, o.delData, cs);
  14287. oper = opers.oper;
  14288. postd[oper] = opers.deloper;
  14289. idname = opers.id;
  14290. postdata = formRowIds.slice();
  14291. if (!postdata.length) { return false; }
  14292. for (pk in postdata) {
  14293. if (postdata.hasOwnProperty(pk)) {
  14294. postdata[pk] = jgrid.stripPref(p.idPrefix, postdata[pk]);
  14295. }
  14296. }
  14297. postd[idname] = postdata.join(o.idSeparator);
  14298. $(this).addClass(activeClass);
  14299. var url = o.url || p.editurl,
  14300. ajaxOptions = $.extend({
  14301. url: $.isFunction(url) ? url.call($t, postd[idname], postd, o, formRowIds) : url,
  14302. type: o.mtype,
  14303. data: $.isFunction(o.serializeDelData) ? o.serializeDelData.call($t, postd, formRowIds) : postd,
  14304. complete: function (jqXHR, textStatus) {
  14305. var i;
  14306. $self.jqGrid("progressBar", { method: "hide", loadtype: o.delui });
  14307. $("#dData", dtbl + "_2").removeClass(activeClass);
  14308. if ((jqXHR.status >= 300 && jqXHR.status !== 304) || (jqXHR.status === 0 && jqXHR.readyState === 4)) {
  14309. ret[0] = false;
  14310. if ($.isFunction(o.errorTextFormat)) {
  14311. ret[1] = o.errorTextFormat.call($t, jqXHR);
  14312. } else {
  14313. ret[1] = textStatus + " Status: '" + jqXHR.statusText + "'. Error code: " + jqXHR.status;
  14314. }
  14315. } else {
  14316. // data is posted successful
  14317. // execute aftersubmit with the returned data from server
  14318. if ($.isFunction(o.afterSubmit)) {
  14319. ret = o.afterSubmit.call($t, jqXHR, postd, formRowIds) || [true];
  14320. }
  14321. }
  14322. if (ret[0] === false) {
  14323. $("#DelError>td", dtbl).html(ret[1]);
  14324. $("#DelError", dtbl).show();
  14325. } else {
  14326. if (p.datatype === "local" || p.treeGrid === true || !o.reloadAfterSubmit) {
  14327. if (p.treeGrid === true) {
  14328. try { base.delTreeNode.call($self, formRowIds[0]); } catch (ignore) { }
  14329. } else {
  14330. formRowIds = formRowIds.slice(); // make copy for save deleting
  14331. for (i = 0; i < formRowIds.length; i++) {
  14332. base.delRowData.call($self, formRowIds[i]);
  14333. }
  14334. }
  14335. }
  14336. if (o.reloadAfterSubmit) {
  14337. $self.trigger("reloadGrid", [$.extend({}, o.reloadGridOptions || {})]);
  14338. }
  14339. setTimeout(function () {
  14340. deleteFeedback("afterComplete", jqXHR, postdata, $(dtbl), formRowIds);
  14341. }, 50);
  14342. }
  14343. o.processing = false;
  14344. if (ret[0]) {
  14345. jgrid.hideModal(themodalSelector, {
  14346. gb: gboxSelector,
  14347. jqm: o.jqModal,
  14348. onClose: o.onClose,
  14349. removemodal: o.removemodal
  14350. });
  14351. }
  14352. }
  14353. }, jgrid.ajaxOptions, o.ajaxDelOptions);
  14354. if (!ajaxOptions.url && !o.useDataProxy) {
  14355. if ($.isFunction(p.dataProxy)) {
  14356. o.useDataProxy = true;
  14357. } else {
  14358. ret[0] = false;
  14359. ret[1] += " " + jgrid.errors.nourl;
  14360. }
  14361. }
  14362. if (ret[0]) {
  14363. $self.jqGrid("progressBar", { method: "show", loadtype: o.delui, htmlcontent: o.deltext });
  14364. if (o.useDataProxy) {
  14365. var dpret = p.dataProxy.call($t, ajaxOptions, "del_" + gridId);
  14366. if (dpret === undefined) {
  14367. dpret = [true, ""];
  14368. }
  14369. if (dpret[0] === false) {
  14370. ret[0] = false;
  14371. ret[1] = dpret[1] || "Error deleting the selected row!";
  14372. } else {
  14373. jgrid.hideModal(themodalSelector, {
  14374. gb: gboxSelector,
  14375. jqm: o.jqModal,
  14376. onClose: o.onClose,
  14377. removemodal: o.removemodal
  14378. });
  14379. }
  14380. } else {
  14381. if (ajaxOptions.url === "clientArray") {
  14382. postd = ajaxOptions.data;
  14383. ajaxOptions.complete({ status: 200, statusText: "" }, "");
  14384. } else {
  14385. $.ajax(ajaxOptions);
  14386. }
  14387. }
  14388. }
  14389. }
  14390. if (ret[0] === false) {
  14391. $("#DelError>td", dtbl).html(ret[1]);
  14392. $("#DelError", dtbl).show();
  14393. }
  14394. return false;
  14395. });
  14396. $("#eData", dtbl + "_2").click(function () {
  14397. jgrid.hideModal(themodalSelector, {
  14398. gb: gboxSelector,
  14399. jqm: o.jqModal,
  14400. onClose: o.onClose,
  14401. removemodal: o.removemodal
  14402. });
  14403. return false;
  14404. });
  14405. deleteFeedback("beforeShowForm", $(dtbl));
  14406. jgrid.viewModal.call($t, themodalSelector, {
  14407. gbox: gboxSelector,
  14408. jqm: o.jqModal,
  14409. overlay: o.overlay,
  14410. toTop: o.toTop,
  14411. modal: o.modal
  14412. });
  14413. deleteFeedback("afterShowForm", $(dtbl));
  14414. }
  14415. if (o.closeOnEscape === true) {
  14416. setTimeout(function () {
  14417. $(".ui-jqdialog-titlebar-close", "#" + jqID(ids.modalhead))
  14418. .attr("tabindex", "-1")
  14419. .focus();
  14420. }, 0);
  14421. }
  14422. });
  14423. },
  14424. navGrid: function (elem, oMuligrid, pEdit, pAdd, pDel, pSearch, pView) {
  14425. if (typeof elem === "object") {
  14426. // the option pager are skipped
  14427. pView = pSearch;
  14428. pSearch = pDel;
  14429. pDel = pAdd;
  14430. pAdd = pEdit;
  14431. pEdit = oMuligrid;
  14432. oMuligrid = elem;
  14433. elem = undefined;
  14434. }
  14435. pAdd = pAdd || {};
  14436. pEdit = pEdit || {};
  14437. pView = pView || {};
  14438. pDel = pDel || {};
  14439. pSearch = pSearch || {};
  14440. return this.each(function () {
  14441. var $t = this, p = $t.p, $self = $($t);
  14442. if (!$t.grid || p == null || ($t.nav && $(elem).find(".navtable").length > 0)) {
  14443. return; // error or the navigator bar already exists
  14444. }
  14445. // make new copy of the options oMuligrid and use it for ONE specific grid.
  14446. // p.navOptions can contains grid specific options
  14447. // we will don't modify the input options oMuligrid
  14448. var gridId = p.id,
  14449. o = $.extend(
  14450. {
  14451. edit: true,
  14452. add: true,
  14453. del: true,
  14454. search: true,
  14455. refresh: true,
  14456. refreshstate: "firstpage",
  14457. view: false,
  14458. closeOnEscape: true,
  14459. beforeRefresh: null,
  14460. afterRefresh: null,
  14461. cloneToTop: false,
  14462. hideEmptyPagerParts: true,
  14463. //jqModal: true,
  14464. alertwidth: 200,
  14465. alertheight: "auto",
  14466. alerttop: null,
  14467. //alertToTop: false,
  14468. removemodal: true,
  14469. alertleft: null,
  14470. alertzIndex: null,
  14471. iconsOverText: false
  14472. },
  14473. base.getGridRes.call($self, "nav"),
  14474. jgrid.nav || {},
  14475. p.navOptions || {},
  14476. oMuligrid || {}
  14477. );
  14478. // set default position depend of RTL/LTR direction of the grid
  14479. o.position = o.position || (p.direction === "rtl" ? "right" : "left");
  14480. var twd, tdw, gridIdEscaped = p.idSel, gboxSelector = p.gBox, commonIconClass = o.commonIconClass,
  14481. alertIDs = { themodal: "alertmod_" + gridId, modalhead: "alerthd_" + gridId, modalcontent: "alertcnt_" + gridId },
  14482. createModalAlert = function () {
  14483. return function () {
  14484. var documentElement = document.documentElement, w = window, left = 1024, top = 768,
  14485. offsetGbox = $self.closest(".ui-jqgrid").offset();
  14486. if ($("#" + jqID(alertIDs.themodal))[0] === undefined) {
  14487. if (!o.alerttop && !o.alertleft) {
  14488. if (w.innerWidth !== undefined) {
  14489. left = w.innerWidth;
  14490. top = w.innerHeight;
  14491. } else if (documentElement != null && documentElement.clientWidth !== undefined && documentElement.clientWidth !== 0) {
  14492. left = documentElement.clientWidth;
  14493. top = documentElement.clientHeight;
  14494. }
  14495. left = left / 2 - parseInt(o.alertwidth, 10) / 2 - offsetGbox.left +
  14496. ((w.pageXOffset !== undefined) ? w.pageXOffset : (documentElement || document.body.parentNode || document.body).scrollLeft);
  14497. top = top / 2 - 25 - offsetGbox.top +
  14498. ((w.pageYOffset !== undefined) ? w.pageYOffset : (documentElement || document.body.parentNode || document.body).scrollTop);
  14499. }
  14500. jgrid.createModal.call($t, alertIDs,
  14501. "<div class='" + getGuiStyles.call($t, "dialog.body") + "'><div>" + o.alerttext + "</div></div>",
  14502. {
  14503. gbox: gboxSelector,
  14504. jqModal: o.jqModal,
  14505. drag: true,
  14506. resize: true,
  14507. caption: o.alertcap,
  14508. top: o.alerttop != null ? o.alerttop : top,
  14509. left: o.alertleft != null ? o.alertleft : left,
  14510. width: o.alertwidth,
  14511. height: o.alertheight,
  14512. closeOnEscape: o.closeOnEscape,
  14513. zIndex: o.alertzIndex,
  14514. removemodal: o.removemodal
  14515. },
  14516. p.gView,
  14517. $(gboxSelector)[0],
  14518. false);
  14519. }
  14520. jgrid.viewModal.call($t, "#" + jqID(alertIDs.themodal), {
  14521. gbox: gboxSelector,
  14522. toTop: o.alertToTop,
  14523. jqm: o.jqModal
  14524. });
  14525. var $close = $("#" + jqID(alertIDs.modalhead)).find(".ui-jqdialog-titlebar-close");
  14526. $close.attr({ tabindex: "0", href: "#", role: "button" });
  14527. setTimeout(function () {
  14528. $close.focus();
  14529. }, 50);
  14530. };
  14531. },
  14532. viewModalAlert = createModalAlert(),
  14533. navtbl,
  14534. clickOnEnter = function (e) {
  14535. var $focused;
  14536. if (e.which === 13) {
  14537. $focused = $(this).find(".ui-pg-button").filter(":focus");
  14538. if ($focused.length > 0) {
  14539. // $focused[0].id == "view_list" or "view_list_top"
  14540. var focusedId = $focused[0].id,
  14541. actionName = focusedId.substr(0,
  14542. $(this).closest(".ui-jqgrid-toppager").length > 0 ?
  14543. focusedId.length - gridId.length - 5 : // "_" + "_top"
  14544. focusedId.length - gridId.length - 1), // view "_"
  14545. gialogId = actionName + "mod" + p.id, // "viewmodlist"
  14546. visibleDailogIds = $(".ui-jqdialog").filter(":visible").map(function () { return this.id; });
  14547. if ($.inArray(gialogId, visibleDailogIds) < 0) {
  14548. // simulate click only if the dialog is not already opened
  14549. $focused.trigger("click");
  14550. return false;
  14551. }
  14552. }
  14553. }
  14554. },
  14555. hoverClasses = getGuiStateStyles.call($t, "hover"),
  14556. disabledClass = getGuiStateStyles.call($t, "disabled"),
  14557. navButtonClass = getGuiStyles.call($t, "navButton", "ui-pg-button");
  14558. if (!$t.grid) {
  14559. return; // error
  14560. }
  14561. // set modalAlert which can be used inside of
  14562. $t.modalAlert = viewModalAlert;
  14563. if (elem === undefined) {
  14564. if (p.pager) {
  14565. elem = p.pager;
  14566. if (p.toppager) {
  14567. o.cloneToTop = true; // add buttons to both pagers
  14568. }
  14569. } else if (p.toppager) {
  14570. elem = p.toppager;
  14571. }
  14572. }
  14573. var clone = 1, i, tbd, pgid, elemids, iPart, pagerTable, $pagerPart, pagerParts = ["left", "center", "right"],
  14574. navButtonDisabledClass = getGuiStyles.call($t, "navButton", "ui-pg-button" + " " + getGuiStateStyles.call($t, "disabled")),
  14575. sep = "<div class='" + navButtonDisabledClass + "'><span class='ui-separator'></span></div>",
  14576. onHoverIn = function () {
  14577. if (!hasOneFromClasses(this, disabledClass)) {
  14578. $(this).addClass(hoverClasses);
  14579. }
  14580. },
  14581. onHoverOut = function () {
  14582. $(this).removeClass(hoverClasses);
  14583. },
  14584. onAdd = function () {
  14585. if (!hasOneFromClasses(this, disabledClass)) {
  14586. if ($.isFunction(o.addfunc)) {
  14587. o.addfunc.call($t, pAdd);
  14588. } else {
  14589. base.editGridRow.call($self, "new", pAdd);
  14590. }
  14591. }
  14592. return false;
  14593. },
  14594. editOrViewOfSelectedRow = function (func, methodName, param) {
  14595. if (!hasOneFromClasses(this, disabledClass)) {
  14596. var sr = p.selrow;
  14597. if (sr) {
  14598. if ($.isFunction(func)) {
  14599. func.call($t, sr, param);
  14600. } else {
  14601. base[methodName].call($self, sr, param);
  14602. }
  14603. } else {
  14604. viewModalAlert();
  14605. }
  14606. }
  14607. return false;
  14608. },
  14609. onEdit = function () {
  14610. return editOrViewOfSelectedRow.call(this, o.editfunc, "editGridRow", pEdit);
  14611. },
  14612. onView = function () {
  14613. return editOrViewOfSelectedRow.call(this, o.viewfunc, "viewGridRow", pView);
  14614. },
  14615. onDel = function () {
  14616. var dr;
  14617. if (!hasOneFromClasses(this, disabledClass)) {
  14618. if (p.multiselect) {
  14619. dr = p.selarrrow;
  14620. if (dr.length === 0) { dr = null; }
  14621. } else {
  14622. dr = p.selrow;
  14623. }
  14624. if (dr) {
  14625. if ($.isFunction(o.delfunc)) {
  14626. o.delfunc.call($t, dr, pDel);
  14627. } else {
  14628. base.delGridRow.call($self, dr, pDel);
  14629. }
  14630. } else {
  14631. viewModalAlert();
  14632. }
  14633. }
  14634. return false;
  14635. },
  14636. onSearch = function () {
  14637. if (!hasOneFromClasses(this, disabledClass)) {
  14638. if ($.isFunction(o.searchfunc)) {
  14639. o.searchfunc.call($t, pSearch);
  14640. } else {
  14641. base.searchGrid.call($self, pSearch);
  14642. }
  14643. }
  14644. return false;
  14645. },
  14646. onRefresh = function () {
  14647. if (!hasOneFromClasses(this, disabledClass)) {
  14648. if ($.isFunction(o.beforeRefresh)) { o.beforeRefresh.call($t); }
  14649. p.search = false;
  14650. p.resetsearch = true;
  14651. try {
  14652. if (o.refreshstate !== "currentfilter") {
  14653. p.postData.filters = "";
  14654. try {
  14655. $("#fbox_" + gridIdEscaped.substr(1)).jqFilter("resetFilter");
  14656. } catch (ignore) { }
  14657. if ($.isFunction($t.clearToolbar)) { $t.clearToolbar(false); }
  14658. }
  14659. } catch (ignore) { }
  14660. switch (o.refreshstate) {
  14661. case "firstpage":
  14662. $self.trigger("reloadGrid", [$.extend({}, o.reloadGridOptions || {}, { page: 1 })]);
  14663. break;
  14664. case "current":
  14665. case "currentfilter":
  14666. $self.trigger("reloadGrid", [$.extend({}, o.reloadGridOptions || {}, { current: true })]);
  14667. break;
  14668. }
  14669. if ($.isFunction(o.afterRefresh)) { o.afterRefresh.call($t); }
  14670. }
  14671. return false;
  14672. },
  14673. stdButtonActivation = function (name, id, onClick) {
  14674. var $button = $("<div class='" + navButtonClass + "' tabindex='0' role='button'></div>"),
  14675. iconClass = o[name + "icon"],
  14676. iconText = $.trim(o[name + "text"]);
  14677. $button.append("<div class='ui-pg-div'><span class='" +
  14678. (o.iconsOverText ?
  14679. mergeCssClasses("ui-pg-button-icon-over-text", commonIconClass, iconClass) :
  14680. mergeCssClasses(commonIconClass, iconClass)) +
  14681. "'></span>" +
  14682. (iconText ? "<span class='ui-pg-button-text" + (o.iconsOverText ? " ui-pg-button-icon-over-text" : "") + "'>" + iconText + "</span>" : "") +
  14683. "</div>");
  14684. $(navtbl).append($button);
  14685. $button.attr({ "title": o[name + "title"] || "", id: id || name + "_" + elemids })
  14686. .click(onClick)
  14687. .hover(onHoverIn, onHoverOut);
  14688. return $button;
  14689. };
  14690. if (o.cloneToTop && p.toppager) { clone = 2; }
  14691. for (i = 0; i < clone; i++) {
  14692. // we can set aria-activedescendant="idOfFirstButton" later
  14693. navtbl = $("<div" + " class='ui-pg-table navtable' role='toolbar' style='float:" +
  14694. (p.direction === "rtl" ? "right" : "left") +
  14695. ";table-layout:auto;'></div>");
  14696. if (i === 0) {
  14697. pgid = elem;
  14698. elemids = gridId;
  14699. if (pgid === p.toppager) {
  14700. elemids += "_top";
  14701. clone = 1;
  14702. }
  14703. } else {
  14704. pgid = p.toppager;
  14705. elemids = gridId + "_top";
  14706. }
  14707. if (o.add) {
  14708. stdButtonActivation("add", pAdd.id, onAdd);
  14709. }
  14710. if (o.edit) {
  14711. stdButtonActivation("edit", pEdit.id, onEdit);
  14712. }
  14713. if (o.view) {
  14714. stdButtonActivation("view", pView.id, onView);
  14715. }
  14716. if (o.del) {
  14717. stdButtonActivation("del", pDel.id, onDel);
  14718. }
  14719. if (o.add || o.edit || o.del || o.view) { $(navtbl).append(sep); }
  14720. if (o.search) {
  14721. tbd = stdButtonActivation("search", pSearch.id, onSearch);
  14722. if (pSearch.showOnLoad && pSearch.showOnLoad === true) {
  14723. $(tbd, navtbl).click();
  14724. }
  14725. }
  14726. if (o.refresh) {
  14727. stdButtonActivation("refresh", "", onRefresh);
  14728. }
  14729. // TODO use setWidthOfPagerTdWithPager or remove at all and use div structure with wrapping
  14730. tdw = $(".ui-jqgrid>.ui-jqgrid-view").css("font-size") || "11px";
  14731. $("body").append("<div id='testpg2' class='" + getGuiStyles.call($t, "gBox", "ui-jqgrid") + "' style='font-size:" + tdw + ";visibility:hidden;' ></div>");
  14732. twd = $(navtbl).clone().appendTo("#testpg2").width();
  14733. $("#testpg2").remove();
  14734. $(pgid + "_" + o.position, pgid).append(navtbl);
  14735. if (o.hideEmptyPagerParts) {
  14736. for (iPart = 0; iPart < pagerParts.length; iPart++) {
  14737. if (pagerParts[iPart] !== o.position) {
  14738. $pagerPart = $(pgid + "_" + pagerParts[iPart], pgid);
  14739. if ($pagerPart.length === 0 || $pagerPart[0].childNodes.length === 0) {
  14740. $pagerPart.hide();
  14741. } else if ($pagerPart[0].childNodes.length === 1) {
  14742. pagerTable = $pagerPart[0].firstChild;
  14743. if ($(pagerTable).is("table.ui-pg-table") && (pagerTable.rows === 0 || pagerTable.rows[0].cells.length === 0)) {
  14744. $pagerPart.hide();
  14745. }
  14746. }
  14747. }
  14748. }
  14749. }
  14750. if (p._nvtd) {
  14751. if (twd > p._nvtd[0]) {
  14752. $(pgid + "_" + o.position, pgid).width(twd);
  14753. p._nvtd[0] = twd;
  14754. }
  14755. p._nvtd[1] = twd;
  14756. }
  14757. $t.nav = true;
  14758. navtbl.on("keydown.jqGrid", clickOnEnter);
  14759. }
  14760. $self.triggerHandler("jqGridResetFrozenHeights");
  14761. });
  14762. },
  14763. navButtonAdd: function (elem, oMuligrid) {
  14764. if (typeof elem === "object") {
  14765. oMuligrid = elem;
  14766. elem = undefined;
  14767. }
  14768. return this.each(function () {
  14769. var $t = this, p = $t.p;
  14770. if (!$t.grid) { return; }
  14771. var o = $.extend(
  14772. {
  14773. caption: "newButton",
  14774. title: "",
  14775. onClickButton: null,
  14776. position: "last",
  14777. iconsOverText: false
  14778. },
  14779. base.getGridRes.call($($t), "nav"),
  14780. jgrid.nav || {},
  14781. p.navOptions || {},
  14782. oMuligrid || {}
  14783. ),
  14784. id = o.id,
  14785. hoverClasses = getGuiStateStyles.call($t, "hover"),
  14786. disabledClass = getGuiStateStyles.call($t, "disabled"),
  14787. navButtonClass = getGuiStyles.call($t, "navButton", "ui-pg-button");
  14788. if (elem === undefined) {
  14789. if (p.pager) {
  14790. base.navButtonAdd.call($($t), p.pager, o);
  14791. if (p.toppager) {
  14792. elem = p.toppager;
  14793. if (id) {
  14794. id += "_top";
  14795. }
  14796. } else {
  14797. return;
  14798. }
  14799. } else if (p.toppager) {
  14800. elem = p.toppager;
  14801. }
  14802. }
  14803. if (typeof elem === "string" && elem.indexOf("#") !== 0) { elem = "#" + jqID(elem); }
  14804. var findnav = $(".navtable", elem), commonIconClass = o.commonIconClass;
  14805. if (findnav.length > 0) {
  14806. if (id && findnav.find("#" + jqID(id)).length > 0) { return; }
  14807. var tbd = $("<div tabindex='0' role='button'></div>");
  14808. if (o.buttonicon.toString().toUpperCase() === "NONE") {
  14809. $(tbd).addClass(navButtonClass).append("<div class='ui-pg-div'>" +
  14810. (o.caption ? "<span class='ui-pg-button-text" + (o.iconsOverText ? " ui-pg-button-icon-over-text" : "") + "'>" + o.caption + "</span>" : "") +
  14811. "</div>");
  14812. } else {
  14813. $(tbd).addClass(navButtonClass).append("<div class='ui-pg-div'>" +
  14814. "<span class='" +
  14815. (o.iconsOverText ?
  14816. mergeCssClasses("ui-pg-button-icon-over-text", commonIconClass, o.buttonicon) :
  14817. mergeCssClasses(commonIconClass, o.buttonicon)) +
  14818. "'></span>" +
  14819. (o.caption ? "<span class='ui-pg-button-text" + (o.iconsOverText ? " ui-pg-button-icon-over-text" : "") + "'>" + o.caption + "</span>" : "") +
  14820. "</div>");
  14821. }
  14822. if (id) { $(tbd).attr("id", id); }
  14823. if (o.position === "first" && findnav.children("div.ui-pg-button").length > 0) {
  14824. findnav.children("div.ui-pg-button").first().before(tbd);
  14825. } else {
  14826. findnav.append(tbd);
  14827. }
  14828. $(tbd, findnav)
  14829. .attr("title", o.title || "")
  14830. .click(function (e) {
  14831. if (!hasOneFromClasses(this, disabledClass)) {
  14832. if ($.isFunction(o.onClickButton)) { o.onClickButton.call($t, o, e); }
  14833. }
  14834. return false;
  14835. })
  14836. .hover(
  14837. function () {
  14838. if (!hasOneFromClasses(this, disabledClass)) {
  14839. $(this).addClass(hoverClasses);
  14840. }
  14841. },
  14842. function () { $(this).removeClass(hoverClasses); }
  14843. );
  14844. $($t).triggerHandler("jqGridResetFrozenHeights");
  14845. }
  14846. });
  14847. },
  14848. navSeparatorAdd: function (elem, o) {
  14849. o = $.extend({
  14850. sepclass: "ui-separator",
  14851. sepcontent: "",
  14852. position: "last"
  14853. }, o || {});
  14854. return this.each(function () {
  14855. if (!this.grid) { return; }
  14856. var $t = this, p = $t.p,
  14857. navButtonClass = getGuiStyles.call($t, "navButton", "ui-pg-button" + " " + getGuiStateStyles.call($t, "disabled"));
  14858. if (elem === undefined) {
  14859. if (p.pager) {
  14860. base.navSeparatorAdd.call($($t), p.pager, o);
  14861. if (p.toppager) {
  14862. elem = p.toppager;
  14863. } else {
  14864. return;
  14865. }
  14866. } else if (p.toppager) {
  14867. elem = p.toppager;
  14868. }
  14869. }
  14870. if (typeof elem === "string" && elem.indexOf("#") !== 0) { elem = "#" + jqID(elem); }
  14871. var $nav = $(".navtable", elem);
  14872. if ($nav.length > 0) {
  14873. var sep = "<div class='" + navButtonClass + "'><span class='" + o.sepclass + "'></span>" + o.sepcontent + "</div>";
  14874. if (o.position === "first") {
  14875. if ($nav.children("div.ui-pg-button").length === 0) {
  14876. $nav.append(sep);
  14877. } else {
  14878. $nav.children("div.ui-pg-button").first().before(sep);
  14879. }
  14880. } else {
  14881. $nav.append(sep);
  14882. }
  14883. }
  14884. });
  14885. },
  14886. GridToForm: function (rowid, formid) {
  14887. return this.each(function () {
  14888. var $t = this, i, $field, iField, $fieldi;
  14889. if (!$t.grid) { return; }
  14890. var rowdata = base.getRowData.call($($t), rowid);
  14891. if (rowdata) {
  14892. for (i in rowdata) {
  14893. if (rowdata.hasOwnProperty(i)) {
  14894. $field = $("[name=" + jqID(i) + "]", formid);
  14895. if ($field.is("input:radio") || $field.is("input:checkbox")) {
  14896. for (iField = 0; iField < $field.length; iField++) {
  14897. $fieldi = $($field[iField]);
  14898. $fieldi.prop("checked", $fieldi.val() === String(rowdata[i]));
  14899. }
  14900. } else {
  14901. // this is very slow on big table and form.
  14902. $field.val(isEmptyString(rowdata[i]) ? "" : rowdata[i]);
  14903. }
  14904. }
  14905. }
  14906. }
  14907. });
  14908. },
  14909. FormToGrid: function (rowid, formid, mode, position) {
  14910. return this.each(function () {
  14911. var $t = this;
  14912. if (!$t.grid) { return; }
  14913. if (!mode) { mode = "set"; }
  14914. if (!position) { position = "first"; }
  14915. var fields = $(formid).serializeArray();
  14916. var griddata = {};
  14917. $.each(fields, function (i, field) {
  14918. griddata[field.name] = field.value;
  14919. });
  14920. if (mode === "add") {
  14921. base.addRowData.call($($t), rowid, griddata, position);
  14922. } else if (mode === "set") {
  14923. base.setRowData.call($($t), rowid, griddata);
  14924. }
  14925. });
  14926. }
  14927. });
  14928. // end module grid.formedit
  14929. // begin module grid.grouping
  14930. jgrid.extend({
  14931. groupingSetup: function () {
  14932. return this.each(function () {
  14933. var $t = this, i, j, cml, p = $t.p, colModel = p.colModel, grp = p.groupingView, cm, summary,
  14934. emptyFormatter = function () {
  14935. return "";
  14936. };
  14937. if (grp !== null && ((typeof grp === "object") || $.isFunction(grp))) {
  14938. if (!grp.groupField.length) {
  14939. p.grouping = false;
  14940. } else {
  14941. if (grp.visibiltyOnNextGrouping === undefined) {
  14942. grp.visibiltyOnNextGrouping = [];
  14943. }
  14944. grp.lastvalues = [];
  14945. if (!grp._locgr) {
  14946. grp.groups = [];
  14947. }
  14948. grp.counters = [];
  14949. for (i = 0; i < grp.groupField.length; i++) {
  14950. if (!grp.groupOrder[i]) {
  14951. grp.groupOrder[i] = "asc";
  14952. }
  14953. if (!grp.groupText[i]) {
  14954. grp.groupText[i] = "{0}";
  14955. }
  14956. if (typeof grp.groupColumnShow[i] !== "boolean") {
  14957. grp.groupColumnShow[i] = true;
  14958. }
  14959. if (typeof grp.groupSummary[i] !== "boolean") {
  14960. grp.groupSummary[i] = false;
  14961. }
  14962. if (!grp.groupSummaryPos[i]) {
  14963. grp.groupSummaryPos[i] = "footer";
  14964. }
  14965. // TODO: allow groupField be from additionalProperties
  14966. // and not only from colModel
  14967. cm = colModel[p.iColByName[grp.groupField[i]]];
  14968. if (grp.groupColumnShow[i] === true) {
  14969. grp.visibiltyOnNextGrouping[i] = true;
  14970. if (cm != null && cm.hidden === true) {
  14971. base.showCol.call($($t), grp.groupField[i]);
  14972. }
  14973. } else {
  14974. grp.visibiltyOnNextGrouping[i] = $("#" + jgrid.jqID(p.id + "_" + grp.groupField[i])).is(":visible");
  14975. if (cm != null && cm.hidden !== true) {
  14976. base.hideCol.call($($t), grp.groupField[i]);
  14977. }
  14978. }
  14979. }
  14980. grp.summary = [];
  14981. if (grp.hideFirstGroupCol) {
  14982. grp.formatDisplayField[0] = function (v) {
  14983. return v;
  14984. };
  14985. }
  14986. for (j = 0, cml = colModel.length; j < cml; j++) {
  14987. cm = colModel[j];
  14988. if (grp.hideFirstGroupCol) {
  14989. if (!cm.hidden && grp.groupField[0] === cm.name) {
  14990. cm.formatter = emptyFormatter;
  14991. }
  14992. }
  14993. if (cm.summaryType) {
  14994. summary = {
  14995. nm: cm.name,
  14996. st: cm.summaryType,
  14997. v: "",
  14998. sr: cm.summaryRound,
  14999. srt: cm.summaryRoundType || "round"
  15000. };
  15001. if (cm.summaryDivider) {
  15002. summary.sd = cm.summaryDivider;
  15003. summary.vd = "";
  15004. }
  15005. grp.summary.push(summary);
  15006. }
  15007. }
  15008. }
  15009. } else {
  15010. p.grouping = false;
  15011. }
  15012. });
  15013. },
  15014. groupingPrepare: function (record, irow) {
  15015. this.each(function () {
  15016. var $t = this, p = $t.p, grp = p.groupingView, groups = grp.groups, counters = grp.counters,
  15017. lastvalues = grp.lastvalues, isInTheSameGroup = grp.isInTheSameGroup, groupLength = grp.groupField.length,
  15018. i, j, keys, newGroup, counter, fieldName, v, displayName, displayValue, changed = false,
  15019. groupingCalculationsHandler = base.groupingCalculations.handler, key,
  15020. buildSummary = function () {
  15021. var iSummary, summary, st;
  15022. for (iSummary = 0; iSummary < counter.summary.length; iSummary++) {
  15023. summary = counter.summary[iSummary];
  15024. st = $.isArray(summary.st) ? summary.st[newGroup.idx] : summary.st;
  15025. if ($.isFunction(st)) {
  15026. summary.v = st.call($t, summary.v, summary.nm, record, newGroup);
  15027. } else {
  15028. summary.v = groupingCalculationsHandler.call($($t), st, summary.v, summary.nm, summary.sr, summary.srt, record);
  15029. if (st.toLowerCase() === "avg" && summary.sd) {
  15030. summary.vd = groupingCalculationsHandler.call($($t), st, summary.vd, summary.sd, summary.sr, summary.srt, record);
  15031. }
  15032. }
  15033. }
  15034. return counter.summary;
  15035. },
  15036. normilizeValue = function (value, cmOrPropName) {
  15037. if (value == null && grp.useDefaultValuesOnGrouping) {
  15038. var cm = p.iColByName[cmOrPropName] !== undefined ?
  15039. p.colModel[p.iColByName[cmOrPropName]] :
  15040. p.additionalProperties[p.iPropByName[cmOrPropName]],
  15041. defaultValue;
  15042. if (cm != null && cm.formatter != null) {
  15043. if (cm.formatoptions != null && cm.formatoptions.defaultValue !== undefined) {
  15044. value = cm.formatoptions.defaultValue;
  15045. } else if (typeof cm.formatter === "string") {
  15046. defaultValue = $($t).jqGrid("getGridRes", "formatter." + cm.formatter + ".defaultValue");
  15047. if (defaultValue !== undefined) {
  15048. value = defaultValue;
  15049. }
  15050. }
  15051. }
  15052. }
  15053. return value;
  15054. };
  15055. for (i = 0; i < groupLength; i++) {
  15056. fieldName = grp.groupField[i];
  15057. v = normilizeValue(record[fieldName], fieldName);
  15058. key = v;
  15059. displayName = grp.displayField[i];
  15060. displayValue = displayName == null ?
  15061. null :
  15062. normilizeValue(record[displayName], displayName);
  15063. if (displayValue == null) {
  15064. displayValue = v;
  15065. }
  15066. if (v !== undefined) {
  15067. keys = [];
  15068. for (j = 0; j <= i; j++) {
  15069. keys.push(record[grp.groupField[j]]);
  15070. }
  15071. newGroup = {
  15072. idx: i, // index in grp.groupField array
  15073. dataIndex: fieldName,
  15074. value: v,
  15075. displayValue: displayValue,
  15076. startRow: irow,
  15077. cnt: 1,
  15078. keys: keys,
  15079. summary: []
  15080. };
  15081. counter = {
  15082. cnt: 1,
  15083. pos: groups.length,
  15084. summary: $.extend(true, [], grp.summary)
  15085. };
  15086. if (irow === 0) {
  15087. // First record always starts a new group
  15088. groups.push(newGroup);
  15089. lastvalues[i] = v;
  15090. counters[i] = counter;
  15091. } else {
  15092. if (typeof v !== "object" && ($.isArray(isInTheSameGroup) && $.isFunction(isInTheSameGroup[i]) ? !isInTheSameGroup[i].call($t, lastvalues[i], v, i, grp) : lastvalues[i] !== v)) {
  15093. // This record is not in same group as previous one
  15094. groups.push(newGroup);
  15095. lastvalues[i] = v;
  15096. changed = true;
  15097. counters[i] = counter;
  15098. } else {
  15099. if (changed) {
  15100. // This group has changed because an earlier group changed.
  15101. groups.push(newGroup);
  15102. lastvalues[i] = v;
  15103. counters[i] = counter;
  15104. } else {
  15105. counter = counters[i];
  15106. counter.cnt += 1;
  15107. groups[counter.pos].cnt = counter.cnt;
  15108. }
  15109. }
  15110. }
  15111. groups[counter.pos].summary = buildSummary();
  15112. for (j = counter.pos - 1; j >= 0; j--) {
  15113. // find the parent group (the grouping header)
  15114. if (groups[j].idx < groups[counter.pos].idx) {
  15115. groups[counter.pos].parentGroupIndex = j;
  15116. groups[counter.pos].parentGroup = groups[j];
  15117. break;
  15118. }
  15119. }
  15120. }
  15121. }
  15122. //gdata.push( rData );
  15123. });
  15124. return this;
  15125. },
  15126. getGroupHeaderIndex: function (hid, clickedElem) {
  15127. var $self = this, self = $self[0], p = self.p,
  15128. $tr = clickedElem ?
  15129. $(clickedElem).closest("tr.jqgroup") :
  15130. $("#" + jgrid.jqID(hid)),
  15131. groupLevel = parseInt($tr.data("jqgrouplevel"), 10),
  15132. hPrefix = p.id + "ghead_" + groupLevel + "_";
  15133. if (isNaN(groupLevel) || !$tr.hasClass("jqgroup") || hid.length <= hPrefix.length) {
  15134. return -1;
  15135. }
  15136. return parseInt(hid.substring(hPrefix.length), 10);
  15137. },
  15138. groupingToggle: function (hid, clickedElem) {
  15139. this.each(function () {
  15140. var $t = this, p = $t.p, grp = p.groupingView,
  15141. minusClasses = grp.minusicon, plusClasses = grp.plusicon,
  15142. $tr = clickedElem ?
  15143. $(clickedElem).closest("tr.jqgroup") :
  15144. $("#" + jgrid.jqID(hid)),
  15145. getGroupHeaderIcon = function ($trElem) {
  15146. return $trElem.find(">td>span." + "tree-wrap");
  15147. },
  15148. itemGroupingLevel, iRowStart, showDataRowsOnExpending = true,
  15149. $groupIcon, collapsed = false, rowsToHideOrShow = [],
  15150. addToHideOrShow = function ($elem) {
  15151. var i, l = $elem.length;
  15152. for (i = 0; i < l; i++) {
  15153. rowsToHideOrShow.push($elem[i]);
  15154. }
  15155. },
  15156. num = parseInt($tr.data("jqgrouplevel"), 10);
  15157. if (p.frozenColumns && $tr.length > 0) {
  15158. // always get row from non-frozen column
  15159. iRowStart = $tr[0].rowIndex;
  15160. $tr = $($t.rows[iRowStart]);
  15161. $tr = $tr.add($t.grid.fbRows[iRowStart]);
  15162. }
  15163. $groupIcon = getGroupHeaderIcon($tr);
  15164. if (jgrid.hasAllClasses($groupIcon, minusClasses)) {
  15165. $groupIcon.removeClass(minusClasses).addClass(plusClasses);
  15166. collapsed = true;
  15167. } else {
  15168. $groupIcon.removeClass(plusClasses).addClass(minusClasses);
  15169. }
  15170. for ($tr = $tr.next(); $tr.length; $tr = $tr.next()) {
  15171. if ($tr.hasClass("jqfoot")) {
  15172. itemGroupingLevel = parseInt($tr.data("jqfootlevel"), 10);
  15173. if (collapsed) {
  15174. // hide all till the summary row of the same level.
  15175. // don't hide the summary row if grp.showSummaryOnHide === true
  15176. itemGroupingLevel = parseInt($tr.data("jqfootlevel"), 10);
  15177. if ((!grp.showSummaryOnHide && itemGroupingLevel === num) || itemGroupingLevel > num) {
  15178. addToHideOrShow($tr);
  15179. }
  15180. // stop hiding of rows if the footer of parent group are found
  15181. if (itemGroupingLevel < num) { break; }
  15182. } else {
  15183. if (itemGroupingLevel === num || (grp.showSummaryOnHide && itemGroupingLevel === num + 1)) {
  15184. addToHideOrShow($tr);
  15185. }
  15186. if (itemGroupingLevel <= num) { break; }
  15187. }
  15188. } else if ($tr.hasClass("jqgroup")) {
  15189. itemGroupingLevel = parseInt($tr.data("jqgrouplevel"), 10);
  15190. if (collapsed) {
  15191. // stop hiding of rows if the grouping header of the next group
  15192. // of the same (or higher) level are found
  15193. if (itemGroupingLevel <= num) { break; }
  15194. addToHideOrShow($tr);
  15195. } else {
  15196. // stop next grouping header of the same lever are found
  15197. if (itemGroupingLevel <= num) { break; }
  15198. if (itemGroupingLevel === num + 1) {
  15199. // one should display subgroupes in collaped form
  15200. getGroupHeaderIcon($tr).removeClass(minusClasses).addClass(plusClasses);
  15201. addToHideOrShow($tr);
  15202. }
  15203. // one need hide all data if subgroup is found
  15204. showDataRowsOnExpending = false;
  15205. }
  15206. } else { // data
  15207. // we set currently no information about the level of data
  15208. // se we use showDataRowsOnExpending variable which will be
  15209. // used during expanding of data
  15210. if (collapsed || showDataRowsOnExpending) {
  15211. // grouping data need be displayed only
  15212. // if the last level group with data (no subgroups)
  15213. // is expanded
  15214. addToHideOrShow($tr);
  15215. }
  15216. }
  15217. }
  15218. //$(rowsToHideOrShow)[collapsed ? "hide" : "show"]();
  15219. $(rowsToHideOrShow).css("display", collapsed ? "none" : "");
  15220. // fix position of elements of frozen divs
  15221. if (p.frozenColumns) {
  15222. $($t).triggerHandler("jqGridResetFrozenHeights", [{
  15223. header: {
  15224. resizeDiv: false,
  15225. resizedRows: {
  15226. iRowStart: -1, // -1 means don't recalculate heights or rows
  15227. iRowEnd: -1
  15228. }
  15229. },
  15230. resizeFooter: false,
  15231. body: {
  15232. resizeDiv: true,
  15233. resizedRows: {
  15234. iRowStart: iRowStart,
  15235. iRowEnd: ($tr.length ? $tr[0].rowIndex - 1 : -1)
  15236. }
  15237. }
  15238. }]);
  15239. }
  15240. // recalculate the width because vertical scrollbar can
  15241. // appears/disappears after expanding/collapsing
  15242. $t.fixScrollOffsetAndhBoxPadding();
  15243. $($t).triggerHandler("jqGridGroupingClickGroup", [hid, collapsed]);
  15244. if ($.isFunction(p.onClickGroup)) {
  15245. p.onClickGroup.call($t, hid, collapsed);
  15246. }
  15247. });
  15248. return false;
  15249. },
  15250. groupingRender: function (grdata, rn) {
  15251. // input parameter grdata is array of strings, which are either opening <tr> element
  15252. // or full HTML fragment (outer HTML) of <td> element, inclusive the closing tag </td>
  15253. // or it contains the closing </tr> tag. The array grdata contains HTML fragments
  15254. // of all rows from the current group.
  15255. // The exact contain of the grdata is the following:
  15256. // "<tr ...>" - the opening tag of the first row of the group
  15257. // "<td>...</td>" - the irst cell of the first row
  15258. // "<td>...</td>" - the second cell of the first row
  15259. // ...
  15260. // "<td>...</td>" - the last cell of the first row
  15261. // "</tr>" - closing tag of the first row of the group
  15262. // "<tr ...>" - the opening tag of the second row of the group
  15263. // ... - all <td> elements of the second row
  15264. // "</tr>" - closing tag of the second row of the group
  15265. // ...
  15266. // "<tr ...>" - the opening tag of the last row of the group
  15267. // ... - all <td> elements of the last row
  15268. // "</tr>" - closing tag of the last row of the group
  15269. // The input parameter rn corresponds to p.rowNum in the most cases.
  15270. var str = "", $t = this[0], p = $t.p, toEnd = 0, cp = [],
  15271. grp = p.groupingView, sumreverse = $.makeArray(grp.groupSummary),
  15272. groupLength = grp.groupField.length, groups = grp.groups, colModel = p.colModel,
  15273. cmLength = colModel.length, page = p.page,
  15274. eventNames = "jqGridShowHideCol.groupingRender",
  15275. getGridRowStyles = function (classes) {
  15276. return base.getGuiStyles.call($t, "gridRow", classes);
  15277. },
  15278. jqgroupClass = getGridRowStyles("jqgroup ui-row-" + p.direction),
  15279. jqfootClass = getGridRowStyles("jqfoot ui-row-" + p.direction);
  15280. function buildSummaryTd(iEndGroup, offset, g, foffset, iconHtml) {
  15281. var fdata = groups[iEndGroup], i, groupCount, strTd = "", tmpdata, colSpan, align, vv,
  15282. madeHidden, nMakeHidden = 0, iSummary, summary, cm, iCol, summaryType, summaryTpl,
  15283. isColumnForIconNotFound = true;
  15284. if (offset !== 0 && groups[iEndGroup].idx !== 0) {
  15285. for (i = iEndGroup; i >= 0; i--) {
  15286. if (groups[i].idx === groups[iEndGroup].idx - offset) {
  15287. fdata = groups[i];
  15288. break;
  15289. }
  15290. }
  15291. }
  15292. groupCount = fdata.cnt;
  15293. for (iCol = (iconHtml === undefined ? foffset : 0); iCol < cmLength; iCol++) {
  15294. tmpdata = "&#160;";
  15295. cm = colModel[iCol];
  15296. for (iSummary = 0; iSummary < fdata.summary.length; iSummary++) {
  15297. summary = fdata.summary[iSummary];
  15298. summaryType = $.isArray(summary.st) ? summary.st[g.idx] : summary.st;
  15299. summaryTpl = $.isArray(cm.summaryTpl) ? cm.summaryTpl[g.idx] : (cm.summaryTpl || "{0}");
  15300. if (summary.nm === cm.name) {
  15301. if (typeof summaryType === "string" && summaryType.toLowerCase() === "avg") {
  15302. if (summary.sd && summary.vd) {
  15303. summary.v = (summary.v / summary.vd);
  15304. } else if (summary.v && groupCount > 0) {
  15305. summary.v = (summary.v / groupCount);
  15306. }
  15307. }
  15308. try {
  15309. summary.groupCount = fdata.cnt;
  15310. summary.groupIndex = fdata.dataIndex;
  15311. summary.groupValue = fdata.value;
  15312. vv = $t.formatter("", summary.v, iCol, summary);
  15313. } catch (ef) {
  15314. vv = summary.v;
  15315. }
  15316. tmpdata = jgrid.format(summaryTpl, vv);
  15317. if (cm.summaryFormat) {
  15318. tmpdata = cm.summaryFormat.call($t, g, tmpdata, vv, cm, summary);
  15319. }
  15320. break;
  15321. }
  15322. }
  15323. colSpan = false;
  15324. align = false;
  15325. if (iconHtml !== undefined && isColumnForIconNotFound) {
  15326. if (!cm.hidden) {
  15327. // the icon need be placed in the first non-hidden column
  15328. tmpdata = iconHtml;
  15329. isColumnForIconNotFound = false;
  15330. if (foffset > 1) {
  15331. colSpan = true;
  15332. // if foffset > 1 then the next foffset-1 non-hidden columns
  15333. // must be displayed hidden.
  15334. nMakeHidden = foffset - 1;
  15335. }
  15336. // the icon in the column header must be left aligned
  15337. align = cm.align; // save the original align value
  15338. cm.align = p.direction === "rtl" ? "right" : "left";
  15339. grp.iconColumnName = cm.name;
  15340. }
  15341. }
  15342. madeHidden = false;
  15343. if (nMakeHidden > 0 && !cm.hidden && tmpdata === "&#160;") {
  15344. madeHidden = true;
  15345. if (align) {
  15346. cm.align = align; // restore the original align value
  15347. }
  15348. nMakeHidden--;
  15349. continue;
  15350. }
  15351. strTd += "<td role='gridcell' " + $t.formatCol(iCol, 1, "") +
  15352. (colSpan ? "colspan='" + foffset + "'" : "") + ">" + tmpdata + "</td>";
  15353. colSpan = false;
  15354. if (align) {
  15355. cm.align = align; // restore the original align value
  15356. }
  15357. if (madeHidden) {
  15358. cm.hidden = false;
  15359. nMakeHidden--;
  15360. }
  15361. }
  15362. return strTd;
  15363. }
  15364. // TODO: allow groupField be from additionalProperties
  15365. // and not only from colModel
  15366. $.each(colModel, function (i, n) {
  15367. var iGroup;
  15368. for (iGroup = 0; iGroup < groupLength; iGroup++) {
  15369. if (grp.groupField[iGroup] === n.name) {
  15370. cp[iGroup] = i;
  15371. break;
  15372. }
  15373. }
  15374. });
  15375. sumreverse.reverse();
  15376. $.each(groups, function (i, n) {
  15377. var gv, clid = p.id + "ghead_" + n.idx, hid = clid + "_" + i,
  15378. groupCollapse = $.isFunction(grp.groupCollapse) ?
  15379. grp.groupCollapse.call($t, { group: n, rowid: hid }) :
  15380. grp.groupCollapse,
  15381. jj, kk, ik, colspan = 1, offset = 0, sgr, gg, end, grpTextStr,
  15382. leaf = groupLength - 1 === n.idx,
  15383. parentGroupCollapse = n.parentGroup != null ?
  15384. n.parentGroup.collapsed :
  15385. false,
  15386. icon = "<span style='cursor:pointer;margin-" +
  15387. (p.direction === "rtl" ? "right:" : "left:") + (n.idx * 12) +
  15388. "px;' class='" + grp.commonIconClass + " " +
  15389. (groupCollapse ? grp.plusicon : grp.minusicon) + " tree-wrap'></span>";
  15390. if (grp._locgr) {
  15391. if (!(n.startRow + n.cnt > (page - 1) * rn && n.startRow < page * rn)) {
  15392. return true;
  15393. }
  15394. }
  15395. if (parentGroupCollapse) {
  15396. groupCollapse = true;
  15397. }
  15398. if (groupCollapse !== undefined) {
  15399. n.collapsed = groupCollapse;
  15400. }
  15401. toEnd++;
  15402. try {
  15403. if ($.isArray(grp.formatDisplayField) && $.isFunction(grp.formatDisplayField[n.idx])) {
  15404. n.displayValue = grp.formatDisplayField[n.idx].call($t, n.displayValue, n.value, colModel[cp[n.idx]], n.idx, n, i);
  15405. gv = n.displayValue;
  15406. } else {
  15407. gv = $t.formatter(hid, n.displayValue, cp[n.idx], n.value, n);
  15408. }
  15409. } catch (egv) {
  15410. gv = n.displayValue;
  15411. }
  15412. str += "<tr id='" + hid + "' data-jqgrouplevel='" + n.idx + "' " +
  15413. (groupCollapse && parentGroupCollapse ? "style='display:none;' " : "") +
  15414. "role='row' class='" + jqgroupClass + " " + clid + "'>";
  15415. grpTextStr = $.isFunction(grp.groupText[n.idx]) ?
  15416. grp.groupText[n.idx].call($t, gv, n.cnt, n.summary) :
  15417. jgrid.template(grp.groupText[n.idx], gv, n.cnt, n.summary);
  15418. if (typeof grpTextStr !== "string" && typeof grpTextStr !== "number") {
  15419. grpTextStr = gv;
  15420. }
  15421. if (grp.groupSummaryPos[n.idx] === "header") {
  15422. colspan = 1;
  15423. if (colModel[0].name === "cb" || colModel[1].name === "cb") {
  15424. colspan++;
  15425. }
  15426. if (colModel[0].name === "subgrid" || colModel[1].name === "subgrid") {
  15427. colspan++;
  15428. }
  15429. str += buildSummaryTd(i, 0, n, colspan, icon + "<span class='cell-wrapper'>" + grpTextStr + "</span>");
  15430. } else {
  15431. str += "<td role='gridcell' style='padding-left:" + (n.idx * 12) + "px;'" +
  15432. " colspan='" + cmLength + "'>" + icon + grpTextStr + "</td>";
  15433. }
  15434. str += "</tr>";
  15435. if (leaf) {
  15436. gg = groups[i + 1];
  15437. sgr = n.startRow;
  15438. end = gg !== undefined ? gg.startRow : groups[i].startRow + groups[i].cnt;
  15439. if (grp._locgr) {
  15440. offset = (page - 1) * rn;
  15441. if (offset > n.startRow) {
  15442. sgr = offset;
  15443. }
  15444. }
  15445. for (kk = sgr; kk < end; kk++) {
  15446. if (!grdata[kk - offset]) {
  15447. break;
  15448. }
  15449. str += grdata[kk - offset].join("");
  15450. }
  15451. if (grp.groupSummaryPos[n.idx] !== "header") {
  15452. if (gg !== undefined) {
  15453. for (jj = 0; jj < grp.groupField.length; jj++) {
  15454. if (gg.dataIndex === grp.groupField[jj]) {
  15455. break;
  15456. }
  15457. }
  15458. toEnd = grp.groupField.length - jj;
  15459. }
  15460. for (ik = 0; ik < toEnd; ik++) {
  15461. if (!sumreverse[ik]) {
  15462. continue;
  15463. }
  15464. str += "<tr data-jqfootlevel='" + (n.idx - ik) +
  15465. (groupCollapse && ((n.idx - ik) > 0 || !grp.showSummaryOnHide) ? "' style='display:none;'" : "'") +
  15466. " role='row' class='" + jqfootClass + "'>";
  15467. str += buildSummaryTd(i, ik, groups[n.idx - ik], 0);
  15468. str += "</tr>";
  15469. }
  15470. toEnd = jj;
  15471. }
  15472. }
  15473. });
  15474. this.off(eventNames)
  15475. .on(eventNames, function () { //e, show, cmName, iColShow) {
  15476. // TODO fix the code after resorting columns
  15477. var iCol = p.iColByName[grp.iconColumnName], iRow, row, iColNew, i; //$cellData;
  15478. if ($.inArray("header", grp.groupSummaryPos) >= 0) {
  15479. for (i = 0; i < colModel.length; i++) {
  15480. if (!colModel[i].hidden) {
  15481. iColNew = i;
  15482. break;
  15483. }
  15484. }
  15485. if (iColNew === undefined || iCol === iColNew) { return; }
  15486. for (iRow = 0; iRow < $t.rows.length; iRow++) {
  15487. row = $t.rows[iRow];
  15488. if ($(row).hasClass("jqgroup")) {
  15489. /*$cellData = $(row.cells[iCol]).children(".cell-wrapper").detach();
  15490. $.wrapInner(row.cells[iColNew], function () {//"<span class='cell-wrapper'></span>");
  15491. return "<span class='cell-wrapper'>" + this.nodeValue + "</span>";
  15492. });
  15493. row.cells[iColNew]
  15494. $cellData = $(row.cells[iCol]).children(".cell-wrapper").detach();
  15495. $(row.cells[iCol]).html($(row.cells[iCol]).children("").html());*/
  15496. $(row.cells[iColNew]).html(row.cells[iCol].innerHTML);
  15497. $(row.cells[iCol]).html("&nbsp;");
  15498. }
  15499. }
  15500. grp.iconColumnName = colModel[iColNew].name;
  15501. }
  15502. });
  15503. return str;
  15504. },
  15505. groupingGroupBy: function (name, options) {
  15506. return this.each(function () {
  15507. var $t = this, p = $t.p, grp = p.groupingView, i, cm;
  15508. if (typeof name === "string") {
  15509. name = [name];
  15510. }
  15511. p.grouping = true;
  15512. grp._locgr = false;
  15513. //Set default, in case visibilityOnNextGrouping is undefined
  15514. if (grp.visibiltyOnNextGrouping === undefined) {
  15515. grp.visibiltyOnNextGrouping = [];
  15516. }
  15517. // show previous hidden groups if they are hidden and weren't removed yet
  15518. for (i = 0; i < grp.groupField.length; i++) {
  15519. cm = p.colModel[p.iColByName[grp.groupField[i]]];
  15520. if (!grp.groupColumnShow[i] && grp.visibiltyOnNextGrouping[i] && cm != null && cm.hidden === true) {
  15521. base.showCol.call($($t), grp.groupField[i]);
  15522. }
  15523. }
  15524. // set visibility status of current group columns on next grouping
  15525. for (i = 0; i < name.length; i++) {
  15526. grp.visibiltyOnNextGrouping[i] = $(p.idSel + "_" + jgrid.jqID(name[i])).is(":visible");
  15527. }
  15528. p.groupingView = $.extend(p.groupingView, options || {});
  15529. grp.groupField = name;
  15530. $($t).trigger("reloadGrid");
  15531. });
  15532. },
  15533. groupingRemove: function (current) {
  15534. return this.each(function () {
  15535. var $t = this, p = $t.p, tbody = $t.tBodies[0], grp = p.groupingView, i;
  15536. if (current === undefined) {
  15537. current = true;
  15538. }
  15539. p.grouping = false;
  15540. if (current === true) {
  15541. // show previous hidden groups if they are hidden and weren't removed yet
  15542. for (i = 0; i < grp.groupField.length; i++) {
  15543. if (!grp.groupColumnShow[i] && grp.visibiltyOnNextGrouping[i]) {
  15544. base.showCol.call($($t), grp.groupField);
  15545. }
  15546. }
  15547. $("tr.jqgroup, tr.jqfoot", tbody).remove();
  15548. $("tr.jqgrow", tbody).filter(":hidden").show();
  15549. } else {
  15550. $($t).trigger("reloadGrid");
  15551. }
  15552. });
  15553. },
  15554. groupingCalculations: {
  15555. handler: function (fn, v, field, round, roundType, rc) {
  15556. var funcs = {
  15557. sum: function () {
  15558. return parseFloat(v || 0) + parseFloat((rc[field] || 0));
  15559. },
  15560. min: function () {
  15561. if (v === "") {
  15562. return parseFloat(rc[field] || 0);
  15563. }
  15564. return Math.min(parseFloat(v), parseFloat(rc[field] || 0));
  15565. },
  15566. max: function () {
  15567. if (v === "") {
  15568. return parseFloat(rc[field] || 0);
  15569. }
  15570. return Math.max(parseFloat(v), parseFloat(rc[field] || 0));
  15571. },
  15572. count: function () {
  15573. if (v === "") {
  15574. v = 0;
  15575. }
  15576. if (rc.hasOwnProperty(field)) {
  15577. return v + 1;
  15578. }
  15579. return 0;
  15580. },
  15581. avg: function () {
  15582. // the same as sum, but at end we divide it
  15583. // so use sum instead of duplicating the code (?)
  15584. return funcs.sum();
  15585. }
  15586. },
  15587. res,
  15588. mul;
  15589. if (!funcs[fn]) {
  15590. throw ("jqGrid Grouping No such method: " + fn);
  15591. }
  15592. res = funcs[fn]();
  15593. if (round != null) {
  15594. if (roundType === "fixed") {
  15595. res = res.toFixed(round);
  15596. } else {
  15597. mul = Math.pow(10, round);
  15598. res = Math.round(res * mul) / mul;
  15599. }
  15600. }
  15601. return res;
  15602. }
  15603. }
  15604. });
  15605. // end module grid.grouping
  15606. /**
  15607. * jqGrid extension for constructing Grid Data from external file
  15608. * Tony Tomov tony@trirand.com, http://trirand.com/blog/
  15609. * Dual licensed under the MIT and GPL licenses:
  15610. * http://www.opensource.org/licenses/mit-license.php
  15611. * http://www.gnu.org/licenses/gpl-2.0.html
  15612. **/
  15613. // begin module grid.import
  15614. $.jgrid.extend({
  15615. jqGridImport: function (o) {
  15616. o = $.extend({
  15617. imptype: "xml", // xml, json, xmlstring, jsonstring
  15618. impstring: "",
  15619. impurl: "",
  15620. mtype: "GET",
  15621. impData: {},
  15622. xmlGrid: {
  15623. config: "roots>grid",
  15624. data: "roots>rows"
  15625. },
  15626. jsonGrid: {
  15627. config: "grid",
  15628. data: "data"
  15629. },
  15630. ajaxOptions: {}
  15631. }, o || {});
  15632. return this.each(function () {
  15633. var $t = this,
  15634. xmlConvert = function (xml, options) {
  15635. var cnfg = $(options.xmlGrid.config, xml)[0], xmldata = $(options.xmlGrid.data, xml)[0], jstr, jstr1, key, svdatatype;
  15636. if (xmlJsonClass.xml2json) {
  15637. jstr = xmlJsonClass.xml2json(cnfg, " ");
  15638. jstr = $.parseJSON(jstr);
  15639. for (key in jstr) {
  15640. if (jstr.hasOwnProperty(key)) {
  15641. jstr1 = jstr[key];
  15642. }
  15643. }
  15644. if (jstr1 !== undefined) {
  15645. if (xmldata) {
  15646. // save the datatype
  15647. svdatatype = jstr.grid.datatype;
  15648. jstr.grid.datatype = "xmlstring";
  15649. jstr.grid.datastr = xml;
  15650. $($t).jqGrid(jstr1).jqGrid("setGridParam", { datatype: svdatatype });
  15651. } else {
  15652. $($t).jqGrid(jstr1);
  15653. }
  15654. }
  15655. } else {
  15656. (jgrid.defaults != null && $.isFunction(jgrid.defaults.fatalError) ? jgrid.defaults.fatalError : alert)("xml2json or parse are not present");
  15657. }
  15658. },
  15659. jsonConvert = function (jsonstr, options) {
  15660. if (jsonstr && typeof jsonstr === "string") {
  15661. var json = $.parseJSON(jsonstr),
  15662. gprm = json[options.jsonGrid.config],
  15663. jdata = json[options.jsonGrid.data], svdatatype;
  15664. if (jdata) {
  15665. svdatatype = gprm.datatype;
  15666. gprm.datatype = "jsonstring";
  15667. gprm.datastr = jdata;
  15668. $($t).jqGrid(gprm).jqGrid("setGridParam", { datatype: svdatatype });
  15669. } else {
  15670. $($t).jqGrid(gprm);
  15671. }
  15672. }
  15673. },
  15674. xmld;
  15675. switch (o.imptype) {
  15676. case "xml":
  15677. $.ajax($.extend({
  15678. url: o.impurl,
  15679. type: o.mtype,
  15680. data: o.impData,
  15681. dataType: "xml",
  15682. context: o,
  15683. complete: function (jqXHR) {
  15684. if ((jqXHR.status < 300 || jqXHR.status === 304) && (jqXHR.status !== 0 || jqXHR.readyState !== 4)) {
  15685. xmlConvert(jqXHR.responseXML, this);
  15686. $($t).triggerHandler("jqGridImportComplete", [jqXHR, this]);
  15687. if ($.isFunction(this.importComplete)) {
  15688. this.importComplete(jqXHR);
  15689. }
  15690. }
  15691. }
  15692. }, o.ajaxOptions));
  15693. break;
  15694. case "xmlstring":
  15695. // we need to make just the conversion and use the same code as xml
  15696. if (o.impstring && typeof o.impstring === "string") {
  15697. xmld = $.parseXML(o.impstring);
  15698. if (xmld) {
  15699. xmlConvert(xmld, o);
  15700. $($t).triggerHandler("jqGridImportComplete", [xmld, o]);
  15701. if ($.isFunction(o.importComplete)) {
  15702. o.importComplete(xmld);
  15703. }
  15704. o.impstring = null;
  15705. }
  15706. }
  15707. break;
  15708. case "json":
  15709. $.ajax($.extend({
  15710. url: o.impurl,
  15711. type: o.mtype,
  15712. data: o.impData,
  15713. dataType: "json",
  15714. context: o,
  15715. complete: function (jqXHR) {
  15716. try {
  15717. if ((jqXHR.status < 300 || jqXHR.status === 304) && (jqXHR.status !== 0 || jqXHR.readyState !== 4)) {
  15718. jsonConvert(jqXHR.responseText, this);
  15719. $($t).triggerHandler("jqGridImportComplete", [jqXHR, this]);
  15720. if ($.isFunction(this.importComplete)) {
  15721. this.importComplete(jqXHR);
  15722. }
  15723. }
  15724. } catch (ignore) { }
  15725. }
  15726. }, o.ajaxOptions));
  15727. break;
  15728. case "jsonstring":
  15729. if (o.impstring && typeof o.impstring === "string") {
  15730. jsonConvert(o.impstring, o);
  15731. $($t).triggerHandler("jqGridImportComplete", [o.impstring, o]);
  15732. if ($.isFunction(o.importComplete)) {
  15733. o.importComplete(o.impstring);
  15734. }
  15735. o.impstring = null;
  15736. }
  15737. break;
  15738. }
  15739. });
  15740. },
  15741. jqGridExport: function (o) {
  15742. o = $.extend({
  15743. exptype: "xmlstring",
  15744. root: "grid",
  15745. ident: "\t"
  15746. }, o || {});
  15747. var ret = null;
  15748. this.each(function () {
  15749. if (!this.grid) {
  15750. return;
  15751. }
  15752. var key, gprm = $.extend(true, {}, $(this).jqGrid("getGridParam"));
  15753. // we need to check for:
  15754. // 1.multiselect, 2.subgrid 3. treegrid and remove the unneded columns from colNames
  15755. if (gprm.rownumbers) {
  15756. gprm.colNames.splice(0, 1);
  15757. gprm.colModel.splice(0, 1);
  15758. }
  15759. if (gprm.multiselect) {
  15760. gprm.colNames.splice(0, 1);
  15761. gprm.colModel.splice(0, 1);
  15762. }
  15763. if (gprm.subGrid) {
  15764. gprm.colNames.splice(0, 1);
  15765. gprm.colModel.splice(0, 1);
  15766. }
  15767. gprm.knv = null;
  15768. if (gprm.treeGrid) {
  15769. for (key in gprm.treeReader) {
  15770. if (gprm.treeReader.hasOwnProperty(key)) {
  15771. gprm.colNames.splice(gprm.colNames.length - 1);
  15772. gprm.colModel.splice(gprm.colModel.length - 1);
  15773. }
  15774. }
  15775. }
  15776. switch (o.exptype) {
  15777. case "xmlstring":
  15778. ret = "<" + o.root + ">" + xmlJsonClass.json2xml(gprm, o.ident) + "</" + o.root + ">";
  15779. break;
  15780. case "jsonstring":
  15781. ret = "{" + xmlJsonClass.toJson(gprm, o.root, o.ident, false) + "}";
  15782. if (gprm.postData.filters !== undefined) {
  15783. ret = ret.replace(/filters":"/, "filters\":");
  15784. ret = ret.replace(/\}\]\}"/, "}]}");
  15785. }
  15786. break;
  15787. }
  15788. });
  15789. return ret;
  15790. },
  15791. excelExport: function (o) {
  15792. o = $.extend({
  15793. exptype: "remote",
  15794. url: null,
  15795. oper: "oper",
  15796. tag: "excel",
  15797. exportOptions: {}
  15798. }, o || {});
  15799. return this.each(function () {
  15800. var pdata;
  15801. if (!this.grid) {
  15802. return;
  15803. }
  15804. if (o.exptype === "remote") {
  15805. pdata = $.extend({}, this.p.postData, o.exportOptions);
  15806. pdata[o.oper] = o.tag;
  15807. window.location = o.url + (o.url != null && o.url.indexOf("?") >= 0 ? "&" : "?") + $.param(pdata);
  15808. }
  15809. });
  15810. }
  15811. });
  15812. // end module grid.import
  15813. /**
  15814. * jqGrid extension for manipulating Grid Data
  15815. * Copyright (c) 2008-2014, Tony Tomov, tony@trirand.com, http://trirand.com/blog/
  15816. * Copyright (c) 2014-2018, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  15817. * Dual licensed under the MIT and GPL licenses:
  15818. * http://www.opensource.org/licenses/mit-license.php
  15819. * http://www.gnu.org/licenses/gpl-2.0.html
  15820. **/
  15821. // begin module grid.inlinedit
  15822. var editFeedback = function (o) {
  15823. var args = $.makeArray(arguments).slice(1);
  15824. args.unshift("");
  15825. args.unshift("Inline");
  15826. args.unshift(o);
  15827. return jgrid.feedback.apply(this, args);
  15828. };
  15829. jgrid.inlineEdit = jgrid.inlineEdit || {};
  15830. jgrid.extend({
  15831. //Editing
  15832. editRow: function (rowid, keys, oneditfunc, successfunc, url, extraparam, aftersavefunc, errorfunc, afterrestorefunc, beforeEditRow) {
  15833. // Compatible mode old versions
  15834. var oMuligrid = {}, args = $.makeArray(arguments).slice(1);
  15835. if ($.type(args[0]) === "object") {
  15836. oMuligrid = args[0];
  15837. } else {
  15838. if (keys !== undefined) { oMuligrid.keys = keys; }
  15839. if ($.isFunction(oneditfunc)) { oMuligrid.oneditfunc = oneditfunc; }
  15840. if ($.isFunction(successfunc)) { oMuligrid.successfunc = successfunc; }
  15841. if (url !== undefined) { oMuligrid.url = url; }
  15842. if (extraparam != null) { oMuligrid.extraparam = extraparam; }
  15843. if ($.isFunction(aftersavefunc)) { oMuligrid.aftersavefunc = aftersavefunc; }
  15844. if ($.isFunction(errorfunc)) { oMuligrid.errorfunc = errorfunc; }
  15845. if ($.isFunction(afterrestorefunc)) { oMuligrid.afterrestorefunc = afterrestorefunc; }
  15846. if ($.isFunction(beforeEditRow)) { oMuligrid.beforeEditRow = beforeEditRow; }
  15847. // last two not as param, but as object (sorry)
  15848. //if (restoreAfterError !== undefined) { oMuligrid.restoreAfterError = restoreAfterError; }
  15849. //if (mtype !== undefined) { oMuligrid.mtype = mtype || "POST"; }
  15850. }
  15851. // End compatible
  15852. return this.each(function () {
  15853. var $t = this, $self = $($t), p = $t.p, cnt = 0, focus = null, svr = {}, editableValues = {}, colModel = p.colModel, opers = p.prmNames;
  15854. if (!$t.grid) { return; }
  15855. var o = $.extend(true, {
  15856. keys: false,
  15857. oneditfunc: null,
  15858. successfunc: null,
  15859. url: null,
  15860. extraparam: {},
  15861. aftersavefunc: null,
  15862. errorfunc: null,
  15863. afterrestorefunc: null,
  15864. restoreAfterError: true,
  15865. beforeEditRow: null,
  15866. //mtype: "POST",
  15867. focusField: true
  15868. }, jgrid.inlineEdit, p.inlineEditing || {}, oMuligrid),
  15869. ind = $self.jqGrid("getInd", rowid, true),
  15870. focusField = o.focusField,
  15871. td = typeof focusField === "object" && focusField != null ?
  15872. $(focusField.target || focusField).closest("tr.jqgrow>td")[0] : null;
  15873. if (ind === false) { return; }
  15874. if (o.extraparam[opers.oper] !== opers.addoper) {
  15875. if (!editFeedback.call($t, o, "beforeEditRow", o, rowid)) { return; }
  15876. }
  15877. if (($(ind).attr("editable") || "0") === "0" && !$(ind).hasClass("not-editable-row")) {
  15878. var editingInfo = jgrid.detectRowEditing.call($t, rowid);
  15879. if (editingInfo != null && editingInfo.mode === "cellEditing") {
  15880. var savedRowInfo = editingInfo.savedRow, tr = $t.rows[savedRowInfo.id],
  15881. highlightClass = getGuiStateStyles.call($t, "select");
  15882. $self.jqGrid("restoreCell", savedRowInfo.id, savedRowInfo.ic);
  15883. // remove highlighting of the cell
  15884. $(tr.cells[savedRowInfo.ic]).removeClass("edit-cell " + highlightClass);
  15885. $(tr).addClass(highlightClass).attr({ "aria-selected": "true", "tabindex": "0" });
  15886. }
  15887. jgrid.enumEditableCells.call($t, ind, $(ind).hasClass("jqgrid-new-row") ? "add" : "edit", function (options) {
  15888. var cm = options.cm, $dataFiled = $(options.dataElement), dataWidth = options.dataWidth, tmp, opt, elc,
  15889. nm = cm.name, edittype = cm.edittype, iCol = options.iCol, editoptions = cm.editoptions || {};
  15890. editableValues[nm] = options.editable;
  15891. if (options.editable === "hidden") { return; }
  15892. try {
  15893. tmp = $.unformat.call(this, options.td, { rowId: rowid, colModel: cm }, iCol);
  15894. } catch (_) {
  15895. tmp = edittype === "textarea" ? $dataFiled.text() : $dataFiled.html();
  15896. }
  15897. svr[nm] = tmp; // include only editable fields in svr object
  15898. $dataFiled.html("");
  15899. opt = $.extend({}, editoptions,
  15900. { id: rowid + "_" + nm, name: nm, rowId: rowid, mode: options.mode, cm: cm, iCol: iCol });
  15901. if (tmp === "&nbsp;" || tmp === "&#160;" || (tmp.length === 1 && tmp.charCodeAt(0) === 160)) { tmp = ""; }
  15902. elc = jgrid.createEl.call($t, edittype, opt, tmp, true, $.extend({}, jgrid.ajaxOptions, p.ajaxSelectOptions || {}));
  15903. $(elc).addClass("editable");
  15904. $dataFiled.append(elc);
  15905. if (dataWidth) {
  15906. // change the width from auto or the value from editoptions
  15907. // in case of editing ExpandColumn of TreeGrid
  15908. $(elc).width(options.dataWidth);
  15909. }
  15910. jgrid.bindEv.call($t, elc, opt);
  15911. //Again IE
  15912. if (edittype === "select" && editoptions.multiple === true && editoptions.dataUrl === undefined && jgrid.msie) {
  15913. $(elc).width($(elc).width());
  15914. }
  15915. if (focus === null) { focus = iCol; }
  15916. cnt++;
  15917. });
  15918. if (cnt > 0) {
  15919. svr.id = rowid;
  15920. p.savedRow.push(svr);
  15921. p.editingInfo[rowid] = {
  15922. mode: "inlineEditing",
  15923. savedRow: svr,
  15924. editable: editableValues
  15925. };
  15926. $(ind).attr("editable", "1");
  15927. if (focusField) {
  15928. if (typeof focusField === "number" && parseInt(focusField, 10) <= colModel.length) {
  15929. focus = focusField;
  15930. } else if (typeof focusField === "string") {
  15931. focus = p.iColByName[focusField];
  15932. } else if (td != null) {
  15933. focus = td.cellIndex;
  15934. }
  15935. setTimeout(function () {
  15936. // we want to use ":focusable"
  15937. var nFrozenColumns = $self.jqGrid("getNumberOfFrozenColumns"),
  15938. getTdByColIndex = function (iCol) {
  15939. return p.frozenColumns && nFrozenColumns > 0 && focus < nFrozenColumns ?
  15940. $t.grid.fbRows[ind.rowIndex].cells[iCol] :
  15941. ind.cells[iCol];
  15942. },
  15943. getFocusable = function (elem) {
  15944. return $(elem).find("input,textarea,select,button,object,*[tabindex]")
  15945. .filter(":input:visible:not(:disabled)");
  15946. },
  15947. getFirstFocusable = function () {
  15948. return getFocusable(p.frozenColumns && nFrozenColumns > 0 ? $t.grid.fbRows[ind.rowIndex] : ind)
  15949. .first();
  15950. },
  15951. $fe = getFocusable(getTdByColIndex(focus));
  15952. if ($fe.length > 0) {
  15953. $fe.first().focus();
  15954. } else if (typeof o.defaultFocusField === "number" || typeof o.defaultFocusField === "string") {
  15955. $fe = getFocusable(getTdByColIndex(typeof o.defaultFocusField === "number" ? o.defaultFocusField : p.iColByName[o.defaultFocusField]));
  15956. if ($fe.length === 0) {
  15957. $fe = getFirstFocusable();
  15958. }
  15959. $fe.first().focus();
  15960. } else {
  15961. getFirstFocusable().focus();
  15962. }
  15963. }, 0);
  15964. }
  15965. if (o.keys === true) {
  15966. var $ind = $(ind);
  15967. if (p.frozenColumns) {
  15968. $ind = $ind.add($t.grid.fbRows[ind.rowIndex]);
  15969. }
  15970. $ind.on("keydown", function (e) {
  15971. if (e.keyCode === 27) {
  15972. $self.jqGrid("restoreRow", rowid, o.afterrestorefunc);
  15973. return false;
  15974. }
  15975. if (e.keyCode === 13) {
  15976. var ta = e.target;
  15977. if (ta.tagName === "TEXTAREA") { return true; }
  15978. $self.jqGrid("saveRow", rowid, o);
  15979. return false;
  15980. }
  15981. });
  15982. }
  15983. fullBoolFeedback.call($t, o.oneditfunc, "jqGridInlineEditRow", rowid, o);
  15984. }
  15985. }
  15986. });
  15987. },
  15988. saveRow: function (rowid, successfunc, url, extraparam, aftersavefunc, errorfunc, afterrestorefunc, beforeSaveRow) {
  15989. // Compatible mode old versions
  15990. var args = $.makeArray(arguments).slice(1), o = {}, $t = this[0], $self = $($t),
  15991. p = $t != null ? $t.p : null, editOrAdd, infoDialog = jgrid.info_dialog,
  15992. isFunction = $.isFunction,
  15993. fatalErrorFunction = jgrid.defaults != null && isFunction(jgrid.defaults.fatalError) ? jgrid.defaults.fatalError : alert;
  15994. if (!$t.grid || p == null) { return; }
  15995. if ($.type(args[0]) === "object") {
  15996. o = args[0];
  15997. } else {
  15998. if (isFunction(successfunc)) { o.successfunc = successfunc; }
  15999. if (url !== undefined) { o.url = url; }
  16000. if (extraparam !== undefined) { o.extraparam = extraparam; }
  16001. if (isFunction(aftersavefunc)) { o.aftersavefunc = aftersavefunc; }
  16002. if (isFunction(errorfunc)) { o.errorfunc = errorfunc; }
  16003. if (isFunction(afterrestorefunc)) { o.afterrestorefunc = afterrestorefunc; }
  16004. if (isFunction(beforeSaveRow)) { o.beforeSaveRow = beforeSaveRow; }
  16005. }
  16006. var getRes = function (path) { return $self.jqGrid("getGridRes", path); };
  16007. o = $.extend(true, {
  16008. successfunc: null,
  16009. url: null,
  16010. extraparam: {},
  16011. aftersavefunc: null,
  16012. errorfunc: null,
  16013. afterrestorefunc: null,
  16014. restoreAfterError: true,
  16015. beforeSaveRow: null,
  16016. ajaxSaveOptions: {},
  16017. serializeSaveData: null,
  16018. mtype: "POST",
  16019. saveui: "enable",
  16020. savetext: getRes("defaults.savetext") || "Saving..."
  16021. }, jgrid.inlineEdit, p.inlineEditing || {}, o);
  16022. // End compatible
  16023. // TODO: add return this.each(function(){....}
  16024. var tmp = {}, tmp2 = {}, postData = {}, editable, k, fr, resp, cv, editingInfo, ind = $self.jqGrid("getInd", rowid, true), $tr = $(ind),
  16025. opers = p.prmNames, errcap = getRes("errors.errcap"), bClose = getRes("edit.bClose"), isRemoteSave, isError,
  16026. displayErrorMessage = function (text, relativeElem) {
  16027. try {
  16028. var relativeRect = jgrid.getRelativeRect.call($t, relativeElem);
  16029. infoDialog.call($t, errcap, text, bClose, {
  16030. top: relativeRect.top,
  16031. left: relativeRect.left + $($t).closest(".ui-jqgrid").offset().left
  16032. });
  16033. } catch (e) {
  16034. fatalErrorFunction(text);
  16035. }
  16036. };
  16037. if (ind === false) { return; }
  16038. editOrAdd = o.extraparam[opers.oper] === opers.addoper ? "add" : "edit";
  16039. if (!editFeedback.call($t, o, "beforeSaveRow", o, rowid, editOrAdd)) { return; }
  16040. editable = $tr.attr("editable");
  16041. o.url = o.url || p.editurl;
  16042. isRemoteSave = o.url !== "clientArray";
  16043. if (editable === "1") {
  16044. editingInfo = $.jgrid.detectRowEditing.call($t, rowid);
  16045. jgrid.enumEditableCells.call($t, ind, $tr.hasClass("jqgrid-new-row") ? "add" : "edit", function (options) {
  16046. var cm = options.cm, formatter = cm.formatter, editoptions = cm.editoptions || {},
  16047. formatoptions = cm.formatoptions || {}, valueText = {},
  16048. v = jgrid.getEditedValue.call($t, $(options.dataElement), cm, valueText, options.editable);
  16049. if (cm.edittype === "select" && cm.formatter !== "select") {
  16050. tmp2[cm.name] = valueText.text;
  16051. }
  16052. cv = jgrid.checkValues.call($t, v, options.iCol, undefined, undefined,
  16053. $.extend(options, {
  16054. oldValue: editingInfo != null ? editingInfo.savedRow[cm.name] : null,
  16055. newValue: v,
  16056. oldRowData: editingInfo != null ? editingInfo.savedRow : null }));
  16057. if (cv != null && cv[0] === false) {
  16058. isError = true;
  16059. displayErrorMessage(cv[1], options.td);
  16060. return false;
  16061. }
  16062. if (formatter === "date" && formatoptions.sendFormatted !== true) {
  16063. // TODO: call all other predefined formatters!!! Not only formatter: "date" have the problem.
  16064. // Floating point separator for example
  16065. v = $.unformat.date.call($t, v, cm);
  16066. }
  16067. if (isRemoteSave && editoptions.NullIfEmpty === true) {
  16068. if (v === "") {
  16069. v = "null";
  16070. }
  16071. }
  16072. tmp[cm.name] = v;
  16073. });
  16074. if (isError) {
  16075. return;
  16076. }
  16077. var idname;
  16078. opers = p.prmNames;
  16079. if (p.keyName === false) {
  16080. idname = opers.id;
  16081. } else {
  16082. idname = p.keyName;
  16083. }
  16084. if (tmp) {
  16085. tmp[opers.oper] = opers.editoper;
  16086. if (tmp[idname] === undefined || tmp[idname] === "") {
  16087. tmp[idname] = jgrid.stripPref(p.idPrefix, rowid);
  16088. }
  16089. tmp = $.extend({}, tmp, p.inlineData || {}, o.extraparam);
  16090. }
  16091. var validationOptions = {
  16092. options: o,
  16093. rowid: rowid,
  16094. tr: ind,
  16095. iRow: ind.rowIndex,
  16096. savedRow: editingInfo.savedRow,
  16097. newData: tmp,
  16098. mode: editOrAdd
  16099. };
  16100. if (!editFeedback.call($t, o, "saveRowValidation", validationOptions)) {
  16101. if (validationOptions.errorText) {
  16102. displayErrorMessage(validationOptions.errorText, ind);
  16103. }
  16104. return;
  16105. }
  16106. if (!isRemoteSave) {
  16107. tmp = $.extend({}, tmp, tmp2);
  16108. resp = $self.jqGrid("setRowData", rowid, tmp);
  16109. $tr.attr("editable", "0");
  16110. for (k = 0; k < p.savedRow.length; k++) {
  16111. if (String(p.savedRow[k].id) === String(rowid)) { fr = k; break; }
  16112. }
  16113. if (fr >= 0) {
  16114. p.savedRow.splice(fr, 1);
  16115. delete p.editingInfo[rowid];
  16116. }
  16117. fullBoolFeedback.call($t, o.aftersavefunc, "jqGridInlineAfterSaveRow", rowid, resp, tmp, o);
  16118. $tr.removeClass("jqgrid-new-row").off("keydown");
  16119. if (ind.id !== p.idPrefix + tmp[idname]) {
  16120. $self.jqGrid("changeRowid", ind.id, p.idPrefix + tmp[idname]);
  16121. }
  16122. } else {
  16123. $self.jqGrid("progressBar", { method: "show", loadtype: o.saveui, htmlcontent: o.savetext });
  16124. postData = $.extend({}, tmp, postData);
  16125. postData[idname] = jgrid.stripPref(p.idPrefix, postData[idname]);
  16126. if (p.autoEncodeOnEdit) {
  16127. $.each(postData, function (n, v) {
  16128. if (!isFunction(v)) {
  16129. postData[n] = jgrid.oldEncodePostedData(v);
  16130. }
  16131. });
  16132. }
  16133. if (ind.id !== p.idPrefix + postData[idname] && opers.idold != null &&
  16134. !postData.hasOwnProperty(opers.idold)) {
  16135. postData[opers.idold] = jgrid.stripPref(p.idPrefix, ind.id);
  16136. }
  16137. $.ajax($.extend({
  16138. url: isFunction(o.url) ? o.url.call($t, postData[idname], editOrAdd, postData, o) : o.url,
  16139. data: jgrid.serializeFeedback.call($t,
  16140. isFunction(o.serializeSaveData) ? o.serializeSaveData : p.serializeRowData,
  16141. "jqGridInlineSerializeSaveData",
  16142. postData),
  16143. type: isFunction(o.mtype) ? o.mtype.call($t, editOrAdd, o, postData[idname], postData) : o.mtype,
  16144. complete: function (jqXHR, textStatus) {
  16145. $self.jqGrid("progressBar", { method: "hide", loadtype: o.saveui });
  16146. // textStatus can be "abort", "timeout", "error", "parsererror" or some text from text part of HTTP error occurs
  16147. // see the answer http://stackoverflow.com/a/3617710/315935 about xhr.readyState === 4 && xhr.status === 0
  16148. if ((jqXHR.status < 300 || jqXHR.status === 304) && (jqXHR.status !== 0 || jqXHR.readyState !== 4)) {
  16149. var ret, sucret, j;
  16150. sucret = $self.triggerHandler("jqGridInlineSuccessSaveRow", [jqXHR, rowid, o, editOrAdd, postData]);
  16151. if (sucret == null || sucret === true) { sucret = [true, tmp]; }
  16152. if (sucret[0] && isFunction(o.successfunc)) { sucret = o.successfunc.call($t, jqXHR, rowid, o, editOrAdd, postData); }
  16153. if ($.isArray(sucret)) {
  16154. // expect array - status, data, rowid
  16155. ret = sucret[0];
  16156. tmp = sucret[1] || tmp;
  16157. } else {
  16158. ret = sucret;
  16159. }
  16160. if (ret === true) {
  16161. if (p.autoEncodeOnEdit) {
  16162. $.each(tmp, function (n, v) {
  16163. tmp[n] = jgrid.oldDecodePostedData(v);
  16164. });
  16165. }
  16166. tmp = $.extend({}, tmp, tmp2);
  16167. $self.jqGrid("setRowData", rowid, tmp);
  16168. $tr.attr("editable", "0");
  16169. for (j = 0; j < p.savedRow.length; j++) {
  16170. if (String(p.savedRow[j].id) === String(rowid)) { fr = j; break; }
  16171. }
  16172. if (fr >= 0) {
  16173. p.savedRow.splice(fr, 1);
  16174. delete p.editingInfo[rowid];
  16175. }
  16176. fullBoolFeedback.call($t, o.aftersavefunc, "jqGridInlineAfterSaveRow", rowid, jqXHR, tmp, o);
  16177. if (sucret[2] != null) {
  16178. $self.jqGrid("changeRowid", rowid, p.idPrefix + sucret[2]);
  16179. } else if (ind.id !== p.idPrefix + tmp[idname]) {
  16180. $self.jqGrid("changeRowid", ind.id, p.idPrefix + tmp[idname]);
  16181. }
  16182. $tr.removeClass("jqgrid-new-row").off("keydown");
  16183. } else {
  16184. fullBoolFeedback.call($t, o.errorfunc, "jqGridInlineErrorSaveRow", rowid, jqXHR, textStatus, null, o);
  16185. if (o.restoreAfterError === true) {
  16186. $self.jqGrid("restoreRow", rowid, o.afterrestorefunc);
  16187. }
  16188. }
  16189. }
  16190. },
  16191. error: function (res, stat, err) {
  16192. $self.triggerHandler("jqGridInlineErrorSaveRow", [rowid, res, stat, err, o]);
  16193. if (isFunction(o.errorfunc)) {
  16194. o.errorfunc.call($t, rowid, res, stat, err);
  16195. } else {
  16196. var rT = res.responseText || res.statusText;
  16197. try {
  16198. infoDialog.call($t, errcap, '<div class="' + getGuiStateStyles.call($t, "error") + '">' + rT + "</div>", bClose, { buttonalign: "right" });
  16199. } catch (e1) {
  16200. fatalErrorFunction(rT);
  16201. }
  16202. }
  16203. if (o.restoreAfterError === true) {
  16204. $self.jqGrid("restoreRow", rowid, o.afterrestorefunc);
  16205. }
  16206. }
  16207. }, jgrid.ajaxOptions, p.ajaxRowOptions, o.ajaxSaveOptions || {}));
  16208. }
  16209. }
  16210. return;
  16211. },
  16212. restoreRow: function (rowid, afterrestorefunc) {
  16213. // Compatible mode old versions
  16214. var args = $.makeArray(arguments).slice(1), oMuligrid = {};
  16215. if ($.type(args[0]) === "object") {
  16216. oMuligrid = args[0];
  16217. } else {
  16218. if ($.isFunction(afterrestorefunc)) { oMuligrid.afterrestorefunc = afterrestorefunc; }
  16219. }
  16220. // End compatible
  16221. return this.each(function () {
  16222. var $t = this, $self = $($t), p = $t.p, fr = -1, ares = {}, k;
  16223. if (!$t.grid) { return; }
  16224. var o = $.extend(true, {}, jgrid.inlineEdit, p.inlineEditing || {}, oMuligrid);
  16225. var ind = $self.jqGrid("getInd", rowid, true);
  16226. if (ind === false) { return; }
  16227. if (!editFeedback.call($t, o, "beforeCancelRow", o, rowid)) { return; }
  16228. for (k = 0; k < p.savedRow.length; k++) {
  16229. if (String(p.savedRow[k].id) === String(rowid)) {
  16230. fr = k;
  16231. break;
  16232. }
  16233. }
  16234. if (fr >= 0) {
  16235. if ($.isFunction($.fn.datepicker)) {
  16236. try {
  16237. $("input.hasDatepicker", "#" + jgrid.jqID(ind.id)).datepicker("hide");
  16238. } catch (ignore) { }
  16239. }
  16240. $.each(p.colModel, function () {
  16241. var nm = this.name;
  16242. if (p.savedRow[fr].hasOwnProperty(nm)) {
  16243. ares[nm] = p.savedRow[fr][nm];
  16244. if (this.formatter && this.formatter === "date" && (this.formatoptions == null || this.formatoptions.sendFormatted !== true)) {
  16245. // TODO: call all other predefined formatters!!! Not only formatter: "date" have the problem.
  16246. // Floating point separator for example
  16247. ares[nm] = $.unformat.date.call($t, ares[nm], this);
  16248. }
  16249. }
  16250. });
  16251. $self.jqGrid("setRowData", rowid, ares);
  16252. $(ind).attr("editable", "0").off("keydown");
  16253. p.savedRow.splice(fr, 1);
  16254. delete p.editingInfo[rowid];
  16255. if ($("#" + jgrid.jqID(rowid), $t).hasClass("jqgrid-new-row")) {
  16256. setTimeout(function () {
  16257. $self.jqGrid("delRowData", rowid);
  16258. $self.jqGrid("showAddEditButtons", false);
  16259. }, 0);
  16260. }
  16261. }
  16262. fullBoolFeedback.call($t, o.afterrestorefunc, "jqGridInlineAfterRestoreRow", rowid);
  16263. });
  16264. },
  16265. addRow: function (oMuligrid) {
  16266. return this.each(function () {
  16267. if (!this.grid) { return; }
  16268. var $t = this, $self = $($t), p = $t.p,
  16269. o = $.extend(true, {
  16270. rowID: null,
  16271. initdata: {},
  16272. position: "first",
  16273. useDefValues: true,
  16274. useFormatter: false,
  16275. beforeAddRow: null,
  16276. //srcRowid: undefined,
  16277. addRowParams: { extraparam: {} }
  16278. }, jgrid.inlineEdit, p.inlineEditing || {}, oMuligrid || {});
  16279. if (!editFeedback.call($t, o, "beforeAddRow", o.addRowParams)) { return; }
  16280. o.rowID = $.isFunction(o.rowID) ? o.rowID.call($t, o) : ((o.rowID != null) ? o.rowID : jgrid.randId());
  16281. if (o.useDefValues === true) {
  16282. $(p.colModel).each(function () {
  16283. if (this.editoptions && this.editoptions.defaultValue) {
  16284. var opt = this.editoptions.defaultValue;
  16285. o.initdata[this.name] = $.isFunction(opt) ? opt.call($t, o) : opt;
  16286. }
  16287. });
  16288. }
  16289. o.rowID = p.idPrefix + o.rowID;
  16290. $self.jqGrid("addRowData", o.rowID, o.initdata, o.position, o.srcRowid);
  16291. $("#" + jgrid.jqID(o.rowID), $t).addClass("jqgrid-new-row");
  16292. if (o.useFormatter) {
  16293. $("#" + jgrid.jqID(o.rowID) + " .ui-inline-edit", $t).click();
  16294. } else {
  16295. var opers = p.prmNames, oper = opers.oper;
  16296. o.addRowParams.extraparam[oper] = opers.addoper;
  16297. $self.jqGrid("editRow", o.rowID, o.addRowParams);
  16298. $self.jqGrid("setSelection", o.rowID);
  16299. }
  16300. });
  16301. },
  16302. inlineNav: function (elem, oMuligrid) {
  16303. if (typeof elem === "object") {
  16304. // the option pager are skipped
  16305. oMuligrid = elem;
  16306. elem = undefined;
  16307. }
  16308. return this.each(function () {
  16309. var $t = this, $self = $($t), p = $t.p;
  16310. if (!this.grid || p == null) { return; }
  16311. var $elem, gID = elem === p.toppager ? p.idSel + "_top" : p.idSel,
  16312. gid = elem === p.toppager ? p.id + "_top" : p.id, disabledClass = getGuiStateStyles.call($t, "disabled"),
  16313. o = $.extend(true,
  16314. {
  16315. edit: true,
  16316. editicon: "ui-icon-pencil",
  16317. add: true,
  16318. addicon: "ui-icon-plus",
  16319. save: true,
  16320. saveicon: "ui-icon-disk",
  16321. cancel: true,
  16322. cancelicon: "ui-icon-cancel",
  16323. commonIconClass: "ui-icon",
  16324. iconsOverText: false,
  16325. //alertToTop: false, use undefined to be able to use defaults from $.jgrid.jqModal or later from p.jqModal
  16326. addParams: { addRowParams: { extraparam: {} } },
  16327. editParams: {},
  16328. restoreAfterSelect: true
  16329. },
  16330. //TODO make getRes(locales[p.locale], "nav"), jgrid.nav || {}, p.navOptions || {}
  16331. // as the result of working getRes("nav")
  16332. //getRes(locales[p.locale], "nav"),
  16333. $self.jqGrid("getGridRes", "nav"),
  16334. jgrid.nav || {},
  16335. p.navOptions || {},
  16336. jgrid.inlineNav || {},
  16337. p.inlineNavOptions || {},
  16338. oMuligrid || {}
  16339. ),
  16340. viewModalAlert = function () {
  16341. $t.modalAlert();
  16342. };
  16343. if (elem === undefined) {
  16344. if (p.pager) {
  16345. $self.jqGrid("inlineNav", p.pager, o);
  16346. if (p.toppager) {
  16347. elem = p.toppager;
  16348. gID = p.idSel + "_top";
  16349. gid = p.id + "_top";
  16350. } else {
  16351. return;
  16352. }
  16353. } else if (p.toppager) {
  16354. elem = p.toppager;
  16355. gID = p.idSel + "_top";
  16356. gid = p.id + "_top";
  16357. }
  16358. }
  16359. if (elem === undefined) {
  16360. return; // error
  16361. }
  16362. $elem = $(elem);
  16363. if ($elem.length <= 0) {
  16364. return; // error
  16365. }
  16366. if ($elem.find(".navtable").length <= 0) {
  16367. // create navigator bar if it is not yet exist
  16368. $self.jqGrid("navGrid", elem, { add: false, edit: false, del: false, search: false, refresh: false, view: false });
  16369. }
  16370. p._inlinenav = true;
  16371. // detect the formatactions column
  16372. if (o.addParams.useFormatter === true) {
  16373. var cm = p.colModel, i, defaults, ap;
  16374. for (i = 0; i < cm.length; i++) {
  16375. if (cm[i].formatter && cm[i].formatter === "actions") {
  16376. if (cm[i].formatoptions) {
  16377. defaults = {
  16378. keys: false,
  16379. onEdit: null,
  16380. onSuccess: null,
  16381. afterSave: null,
  16382. onError: null,
  16383. afterRestore: null,
  16384. extraparam: {},
  16385. url: null
  16386. };
  16387. ap = $.extend(defaults, cm[i].formatoptions);
  16388. o.addParams.addRowParams = {
  16389. "keys": ap.keys,
  16390. "oneditfunc": ap.onEdit,
  16391. "successfunc": ap.onSuccess,
  16392. "url": ap.url,
  16393. "extraparam": ap.extraparam,
  16394. "aftersavefunc": ap.afterSave,
  16395. "errorfunc": ap.onError,
  16396. "afterrestorefunc": ap.afterRestore
  16397. };
  16398. }
  16399. break;
  16400. }
  16401. }
  16402. }
  16403. if (o.add) {
  16404. $self.jqGrid("navButtonAdd", elem, {
  16405. caption: o.addtext,
  16406. title: o.addtitle,
  16407. commonIconClass: o.commonIconClass,
  16408. buttonicon: o.addicon,
  16409. iconsOverText: o.iconsOverText,
  16410. id: gid + "_iladd",
  16411. onClickButton: function () {
  16412. if (!hasOneFromClasses(this, disabledClass)) {
  16413. $self.jqGrid("addRow", o.addParams);
  16414. }
  16415. }
  16416. });
  16417. }
  16418. if (o.edit) {
  16419. $self.jqGrid("navButtonAdd", elem, {
  16420. caption: o.edittext,
  16421. title: o.edittitle,
  16422. commonIconClass: o.commonIconClass,
  16423. buttonicon: o.editicon,
  16424. iconsOverText: o.iconsOverText,
  16425. id: gid + "_iledit",
  16426. onClickButton: function () {
  16427. if (!hasOneFromClasses(this, disabledClass)) {
  16428. var sr = p.selrow;
  16429. if (sr) {
  16430. $self.jqGrid("editRow", sr, o.editParams);
  16431. } else {
  16432. viewModalAlert();
  16433. }
  16434. }
  16435. }
  16436. });
  16437. }
  16438. if (o.save) {
  16439. $self.jqGrid("navButtonAdd", elem, {
  16440. caption: o.savetext,
  16441. title: o.savetitle,
  16442. commonIconClass: o.commonIconClass,
  16443. buttonicon: o.saveicon,
  16444. iconsOverText: o.iconsOverText,
  16445. id: gid + "_ilsave",
  16446. onClickButton: function () {
  16447. if (!hasOneFromClasses(this, disabledClass) && p.savedRow.length > 0) {
  16448. var sr = p.savedRow[0].id;
  16449. if (sr) {
  16450. var opers = p.prmNames, oper = opers.oper, tmpParams = o.editParams;
  16451. if ($("#" + jgrid.jqID(sr), $t).hasClass("jqgrid-new-row")) {
  16452. o.addParams.addRowParams.extraparam[oper] = opers.addoper;
  16453. tmpParams = o.addParams.addRowParams;
  16454. } else {
  16455. if (!o.editParams.extraparam) {
  16456. o.editParams.extraparam = {};
  16457. }
  16458. o.editParams.extraparam[oper] = opers.editoper;
  16459. }
  16460. $self.jqGrid("saveRow", sr, tmpParams);
  16461. } else {
  16462. viewModalAlert();
  16463. }
  16464. }
  16465. }
  16466. });
  16467. $(gID + "_ilsave").addClass(disabledClass);
  16468. }
  16469. if (o.cancel) {
  16470. $self.jqGrid("navButtonAdd", elem, {
  16471. caption: o.canceltext,
  16472. title: o.canceltitle,
  16473. commonIconClass: o.commonIconClass,
  16474. buttonicon: o.cancelicon,
  16475. iconsOverText: o.iconsOverText,
  16476. id: gid + "_ilcancel",
  16477. onClickButton: function () {
  16478. if (!hasOneFromClasses(this, disabledClass) && p.savedRow.length > 0) {
  16479. var sr = p.savedRow[0].id, cancelPrm = o.editParams;
  16480. if (sr) {
  16481. if ($("#" + jgrid.jqID(sr), $t).hasClass("jqgrid-new-row")) {
  16482. cancelPrm = o.addParams.addRowParams;
  16483. }
  16484. $self.jqGrid("restoreRow", sr, cancelPrm);
  16485. } else {
  16486. viewModalAlert();
  16487. }
  16488. }
  16489. }
  16490. });
  16491. $(gID + "_ilcancel").addClass(disabledClass);
  16492. }
  16493. if (o.restoreAfterSelect === true) {
  16494. $self.on("jqGridSelectRow", function (e, rowid) {
  16495. if (p.savedRow.length > 0 && p._inlinenav === true) {
  16496. var editingRowId = p.savedRow[0].id;
  16497. if (rowid !== editingRowId && typeof editingRowId !== "number") {
  16498. $self.jqGrid("restoreRow", editingRowId, o.editParams);
  16499. }
  16500. }
  16501. });
  16502. }
  16503. $self.on("jqGridInlineAfterRestoreRow jqGridInlineAfterSaveRow", function () {
  16504. $self.jqGrid("showAddEditButtons", false);
  16505. });
  16506. $self.on("jqGridInlineEditRow", function (e, rowid) {
  16507. $self.jqGrid("showAddEditButtons", true, rowid);
  16508. });
  16509. });
  16510. },
  16511. showAddEditButtons: function (isEditing) {
  16512. return this.each(function () {
  16513. var $t = this;
  16514. if (!$t.grid) { return; }
  16515. var p = $t.p, idSel = p.idSel, disabledClass = getGuiStateStyles.call($t, "disabled"),
  16516. saveCancel = idSel + "_ilsave," + idSel + "_ilcancel" + (p.toppager ? "," + idSel + "_top_ilsave," + idSel + "_top_ilcancel" : ""),
  16517. addEdit = idSel + "_iladd," + idSel + "_iledit" + (p.toppager ? "," + idSel + "_top_iladd," + idSel + "_top_iledit" : "");
  16518. $(isEditing ? addEdit : saveCancel).addClass(disabledClass);
  16519. $(isEditing ? saveCancel : addEdit).removeClass(disabledClass);
  16520. });
  16521. }
  16522. });
  16523. // end module grid.inlinedit
  16524. /**
  16525. * jqGrid addons using jQuery UI
  16526. * Author: Mark Williams
  16527. * Changed by Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  16528. * Dual licensed under the MIT and GPL licenses:
  16529. * http://www.opensource.org/licenses/mit-license.php
  16530. * http://www.gnu.org/licenses/gpl-2.0.html
  16531. * depends on jQuery UI
  16532. **/
  16533. // begin module grid.jqueryui
  16534. var $UiMultiselect = $.ui != null ? $.ui.multiselect : null,
  16535. reorderSelectedColumns = function (iColItem) {
  16536. /* Background information:
  16537. *
  16538. * Multiselect contains the list of selected items this.selectedList,
  16539. * which is jQuery wrapper of <ul> element. The items of this.selectedList
  16540. * are <li> elements, which represent visible (hidden:false) and movable
  16541. * (hidedlg:false) columns of the grid.
  16542. *
  16543. * Additionally there are exist hidden <select multiple="multiple">.
  16544. * Every <option> of the <select> corresponds the column of the grid.
  16545. * The visible columns (hidden:false) are selected. The value of the <option>
  16546. * contains the column index (iCol) in colModel. <li> elements of
  16547. * this.selectedLis have data with the "optionLink" pointed to the corresponding
  16548. * option of the hidden select.
  16549. *
  16550. * this.grid is the DOM of the grid and this.newColOrder is the array with
  16551. * ALL column names in the order, which should be applied after reordering
  16552. * the grid. Additionally this.gh contains the COPY of p.groupHeader.groupHeaders.
  16553. * It's important that startColumnName property of elements of
  16554. * p.groupHeader.groupHeaders could be changed during reordering of the columns.
  16555. * On the other side the user can't click Cancel button of columnChooser for
  16556. * breaking reordering. Because of that this.gh contains the COPY of
  16557. * p.groupHeader.groupHeaders and the original p.groupHeader.groupHeaders will be
  16558. * not changed in the reorderSelectedColumns function.
  16559. *
  16560. * An important implementation problem: reorderSelectedColumns function will be
  16561. * called after ONE reordering of the columns. On the other side, the user can
  16562. * reorder the columns MULTIPLE TIMES before saving the new order. Thus, one
  16563. * have to take in consideration not only the original order of columns in
  16564. * colModel, but THE CURRENT order of the columns saved only internally in
  16565. * the dialog in this.newColOrder.
  16566. */
  16567. if (this.grid != null && this.grid.p != null) {
  16568. var that = this, p = this.grid.p, iCol, j, iGrp, ghItem,
  16569. gh = this.gh, selectedList = this.selectedList, inGroup = this.inGroup,
  16570. items = selectedList.find("li"), optionLink,
  16571. indexOfAddedItem = items.length - 1,
  16572. enumSelected = function (callback, startIndex, reverse) {
  16573. var i, opt, items = selectedList.find("li");
  16574. if (startIndex === undefined) {
  16575. startIndex = reverse ? items.length - 1 : 0;
  16576. }
  16577. for (i = startIndex; !reverse ? i < items.length : i >= 0; !reverse ? i++ : i--) {
  16578. opt = $(items[i]).data("optionLink");
  16579. if (opt && callback.call(items[i], parseInt(opt.val(), 10), i)) {
  16580. return i;
  16581. }
  16582. }
  16583. },
  16584. updateNewColOrder = function () {
  16585. // !!! the function set additionally indexOfAddedItem and update items
  16586. // remove iColItem from this.newColOrder
  16587. j = $.inArray(p.colModel[iColItem].name, that.newColOrder);
  16588. if (j >= 0) {
  16589. that.newColOrder.splice(j, 1);
  16590. }
  16591. // refill items
  16592. items = selectedList.find("li");
  16593. // iCol will be the index in newColOrder. The order of columns in items
  16594. // should be mostly THE SAME like in selectedList, but newColOrder
  16595. // contains additional elements (hidden and hidedlg). The array items
  16596. // on the other side contains just inserted iColItem element.
  16597. // we need find indexOfAddedItem - the index of <li> with iColItem
  16598. // in the list of this.selectedList.find("li") elements
  16599. iCol = 0;
  16600. enumSelected(
  16601. function (iColOld, index) {
  16602. if (iColOld === iColItem) {
  16603. indexOfAddedItem = index;
  16604. // if iColItem is in the same header group as p.colModel[iCol] or
  16605. // both belongs no header group then the column could be NOT in
  16606. // selectedList. I find better to insert the item AFTER the hidden
  16607. // or non-movable columns (like "rn", "subgrid" column or other)
  16608. while (iCol >= 0 && iCol < p.colModel.length && iCol !== iColItem &&
  16609. (p.colModel[iCol].hidden || p.colModel[iCol].hidedlg) &&
  16610. (inGroup == null ||
  16611. //inGroup[iCol] !== undefined && inGroup[iColItem] !== undefined &&
  16612. inGroup[iCol] === inGroup[iColItem])) {
  16613. iCol++;
  16614. }
  16615. that.newColOrder.splice(iCol, 0, p.colModel[iColItem].name);
  16616. return true; // stop enumeration
  16617. }
  16618. // selectedList contains SUBSET of columns from colModel, but newColOrder
  16619. // contains ALL columns. It's important that all columns from selectedList
  16620. // exist in newColOrder IN THE SAME order. Thus iCol will be the current
  16621. // index in newColOrder array with p.colModel[iColOld].name column name.
  16622. iCol = $.inArray(p.colModel[iColOld].name, that.newColOrder, iCol);
  16623. if (iCol < 0) {
  16624. // to be sure that the code works in case of some errors too
  16625. iCol = $.inArray(p.colModel[iColOld].name, that.newColOrder);
  16626. }
  16627. iCol++;
  16628. }
  16629. );
  16630. },
  16631. enumPreviousAndInsertAfter = function (iCol) {
  16632. if (inGroup[iCol] === inGroup[iColItem]) {
  16633. $(this).after(items[indexOfAddedItem]);
  16634. updateNewColOrder();
  16635. return true; // stop enumeration
  16636. }
  16637. },
  16638. enumNextAndInsertBefore = function (iCol) {
  16639. if (inGroup[iCol] === inGroup[iColItem]) {
  16640. $(this).before(items[indexOfAddedItem]);
  16641. updateNewColOrder();
  16642. return true; // stop enumeration
  16643. }
  16644. },
  16645. updateStartColumn = function (iCol) {
  16646. if (inGroup[iCol] === inGroup[iColItem] && inGroup[iCol] !== undefined) {
  16647. gh[inGroup[iCol]].startColumnName = p.colModel[iCol].name;
  16648. return true; // stop enumeration
  16649. }
  16650. };
  16651. // Fix potition of added/moved item iColItem in that.newColOrder array.
  16652. // We syncronize only the initial state of newColOrder. The position of
  16653. // iColItem item can be changed later in both selectedList and newColOrder
  16654. updateNewColOrder();
  16655. if (gh && gh[inGroup[iColItem]] !== undefined) {
  16656. // the item belong to some group
  16657. ghItem = gh[inGroup[iColItem]];
  16658. for (j = 0; j < ghItem.numberOfColumns; j++) {
  16659. iCol = p.iColByName[ghItem.startColumnName] + j;
  16660. if (!p.colModel[iCol].hidden && !p.colModel[iCol].hidedlg) {
  16661. // the columns are displayed in the selectedList
  16662. // We need to enumerate items in reverse order and to find the index of the item
  16663. // in the array items comparing the items by $(items[j]).data("optionLink").val()
  16664. // If the item is found then append prevously found item AFTER this one.
  16665. // We can use j variable bacause the outer loop will be exit (see break below)
  16666. enumSelected(
  16667. enumPreviousAndInsertAfter,
  16668. indexOfAddedItem - 1,
  16669. true // enum in reverse order
  16670. );
  16671. // If step 2 didn't find the group then we need examin NEXT items and find
  16672. // the items from the same group. We should test the items in sequential order
  16673. // after the item found. If the item is found then apend prevously found
  16674. // item BEFORE this one.
  16675. enumSelected(
  16676. enumNextAndInsertBefore,
  16677. indexOfAddedItem + 1
  16678. );
  16679. // fix the name of the first column in the group
  16680. enumSelected(updateStartColumn);
  16681. break; // !!!
  16682. }
  16683. }
  16684. } else if (gh) {
  16685. // The item from no group is added/moved.
  16686. // We have to verify that the item is not dropped inside of some header group
  16687. // find the index of added/moved element in this.selectedList.find("li")
  16688. items = selectedList.find("li");
  16689. j = enumSelected(function (iCol) {
  16690. if (iCol === iColItem) {
  16691. return true;
  16692. }
  16693. });
  16694. if (j + 1 >= items.length || j < 0) {
  16695. return;
  16696. }
  16697. optionLink = $(items[j + 1]).data("optionLink");
  16698. if (optionLink) {
  16699. iGrp = inGroup[parseInt(optionLink.val(), 10)];
  16700. if (iGrp !== undefined) {
  16701. optionLink = $(items[j - 1]).data("optionLink");
  16702. if (optionLink && inGroup[parseInt(optionLink.val(), 10)] === iGrp) {
  16703. // The next and the previous items are in the same group, but
  16704. // the added/moved item in NOT in the group.
  16705. // We have to move the item items[j] AFTER the last item of the group.
  16706. var iColNotInTheGroup = enumSelected(
  16707. function (iCol) {
  16708. if (inGroup[iCol] !== iGrp) {
  16709. return true; // stop enumeration
  16710. }
  16711. },
  16712. j + 1 // start enumeration with the index
  16713. );
  16714. $(items[iColNotInTheGroup === undefined || iColNotInTheGroup >= items.length ? items.length - 1 : iColNotInTheGroup - 1])
  16715. .after(items[indexOfAddedItem]);
  16716. updateNewColOrder();
  16717. }
  16718. }
  16719. }
  16720. }
  16721. }
  16722. };
  16723. if (jgrid.msie && jgrid.msiever() === 8) {
  16724. $.expr[":"].hidden = function (elem) {
  16725. return elem.offsetWidth === 0 || elem.offsetHeight === 0 ||
  16726. elem.style.display === "none";
  16727. };
  16728. }
  16729. // requiere load multiselect before grid
  16730. jgrid._multiselect = false;
  16731. if ($UiMultiselect) {
  16732. if ($UiMultiselect.prototype._setSelected) {
  16733. var setSelected = $UiMultiselect.prototype._setSelected;
  16734. $UiMultiselect.prototype._setSelected = function (item, selected) {
  16735. // the method will be called if the user clicks "+" button on the item of "available" list
  16736. // or if the user clicks "-" button on the item of "selected" list.
  16737. // The parameter "selected" is equal true on click on the item of "selected" list
  16738. // and false on click on the item of "available" list.
  16739. var ret = setSelected.call(this, item, selected), elt = this.element,
  16740. iColItem = parseInt(item.data("optionLink").val(), 10);
  16741. if (selected && this.selectedList) {
  16742. // reorder items of selectedList
  16743. // all items of selectedList from one group have to be together
  16744. // all items of availableList from one group have to be together
  16745. reorderSelectedColumns.call(this, iColItem);
  16746. // apply the new sort order to the original selectbox
  16747. this.selectedList.find("li").each(function () {
  16748. if ($(this).data("optionLink")) {
  16749. $(this).data("optionLink").remove().appendTo(elt);
  16750. }
  16751. });
  16752. }
  16753. return ret;
  16754. };
  16755. }
  16756. if ($UiMultiselect.prototype.destroy) {
  16757. $UiMultiselect.prototype.destroy = function () {
  16758. var self = this;
  16759. self.element.show();
  16760. self.container.remove();
  16761. if ($.Widget === undefined) {
  16762. $.widget.prototype.destroy.apply(self, arguments);
  16763. } else {
  16764. $.Widget.prototype.destroy.apply(self, arguments);
  16765. }
  16766. };
  16767. }
  16768. jgrid._multiselect = true;
  16769. }
  16770. jgrid.extend({
  16771. sortableColumns: function (tblrow) {
  16772. return this.each(function () {
  16773. var ts = this, p = ts.p, tid = jqID(p.id);
  16774. if (!p || !p.sortable || !$.isFunction($.fn.sortable)) { return; }
  16775. function start() { p.disableClick = true; }
  16776. var sortableOpts = {
  16777. tolerance: "pointer",
  16778. axis: "x",
  16779. scrollSensitivity: "1",
  16780. items: ">th:not(:has(#jqgh_" + tid + "_cb" + ",#jqgh_" + tid + "_rn" + ",#jqgh_" + tid + "_subgrid),:hidden)",
  16781. placeholder: {
  16782. element: function (item) {
  16783. var el = $(document.createElement(item[0].nodeName))
  16784. .addClass(item[0].className + " ui-sortable-placeholder ui-state-highlight")
  16785. .removeClass("ui-sortable-helper")[0];
  16786. return el;
  16787. },
  16788. update: function (self, o) {
  16789. o.height(self.currentItem.innerHeight() - parseInt(self.currentItem.css("paddingTop") || 0, 10) - parseInt(self.currentItem.css("paddingBottom") || 0, 10));
  16790. o.width(self.currentItem.innerWidth() - parseInt(self.currentItem.css("paddingLeft") || 0, 10) - parseInt(self.currentItem.css("paddingRight") || 0, 10));
  16791. }
  16792. },
  16793. start: function () {
  16794. ts.grid.hDiv.scrollLeft = ts.grid.bDiv.scrollLeft;
  16795. },
  16796. update: function (event, ui) {
  16797. var th = $(">th", $(ui.item).parent()), tid1 = p.id + "_", permutation = [];
  16798. th.each(function () {
  16799. var id = $(">div", this).get(0).id.replace(/^jqgh_/, "").replace(tid1, ""),
  16800. iCol = p.iColByName[id];
  16801. if (iCol !== undefined) {
  16802. permutation.push(iCol);
  16803. }
  16804. });
  16805. $(ts).jqGrid("remapColumns", permutation, true, true);
  16806. if ($.isFunction(p.sortable.update)) {
  16807. p.sortable.update(permutation);
  16808. }
  16809. setTimeout(function () { p.disableClick = false; }, 50);
  16810. }
  16811. };
  16812. if (p.sortable.options) {
  16813. $.extend(sortableOpts, p.sortable.options);
  16814. } else if ($.isFunction(p.sortable)) {
  16815. p.sortable = { "update": p.sortable };
  16816. }
  16817. if (sortableOpts.start) {
  16818. var s = sortableOpts.start;
  16819. sortableOpts.start = function (e, ui) {
  16820. start();
  16821. s.call(this, e, ui);
  16822. };
  16823. } else {
  16824. sortableOpts.start = start;
  16825. }
  16826. if (p.sortable.exclude) {
  16827. sortableOpts.items += ":not(" + p.sortable.exclude + ")";
  16828. }
  16829. var $e = tblrow.sortable(sortableOpts), dataObj = $e.data("sortable") || $e.data("uiSortable") || $e.data("ui-sortable");
  16830. if (dataObj != null) {
  16831. dataObj.floating = true;
  16832. }
  16833. });
  16834. },
  16835. columnChooser: function (opts) {
  16836. var $self = this, self = $self[0], p = self.p, selector, select, dopts, mopts,
  16837. $dialogContent, multiselectData, listHeight,
  16838. colModel = p.colModel, nCol = colModel.length, colNames = p.colNames,
  16839. getMultiselectWidgetData = function ($elem) {
  16840. return ($UiMultiselect && $UiMultiselect.prototype && $elem.data($UiMultiselect.prototype.widgetFullName || $UiMultiselect.prototype.widgetName)) ||
  16841. $elem.data("ui-multiselect") || $elem.data("multiselect");
  16842. };
  16843. if ($("#colchooser_" + jqID(p.id)).length) { return; }
  16844. selector = $('<div id="colchooser_' + p.id + '" style="position:relative;overflow:hidden"><div><select multiple="multiple"></select></div></div>');
  16845. select = $("select", selector);
  16846. function call(fn, obj) {
  16847. if (!fn) { return; }
  16848. if (typeof fn === "string") {
  16849. if ($.fn[fn]) {
  16850. $.fn[fn].apply(obj, $.makeArray(arguments).slice(2));
  16851. }
  16852. } else if ($.isFunction(fn)) {
  16853. fn.apply(obj, $.makeArray(arguments).slice(2));
  16854. }
  16855. }
  16856. opts = $.extend({
  16857. width: 400,
  16858. height: 240,
  16859. classname: null,
  16860. done: function (perm) {
  16861. if (perm) {
  16862. $self.jqGrid("remapColumns", perm, true);
  16863. }
  16864. },
  16865. /* msel is either the name of a ui widget class that
  16866. extends a multiselect, or a function that supports
  16867. creating a multiselect object (with no argument,
  16868. or when passed an object), and destroying it (when
  16869. passed the string "destroy"). */
  16870. msel: "multiselect",
  16871. /* "msel_opts" : {}, */
  16872. /* dlog is either the name of a ui widget class that
  16873. behaves in a dialog-like way, or a function, that
  16874. supports creating a dialog (when passed dlog_opts)
  16875. or destroying a dialog (when passed the string
  16876. "destroy")
  16877. */
  16878. dlog: "dialog",
  16879. dialog_opts: {
  16880. minWidth: 470,
  16881. dialogClass: "ui-jqdialog"
  16882. },
  16883. /* dlog_opts is either an option object to be passed
  16884. to "dlog", or (more likely) a function that creates
  16885. the options object.
  16886. The default produces a suitable options object for
  16887. ui.dialog */
  16888. dlog_opts: function (options) {
  16889. var buttons = {};
  16890. buttons[options.bSubmit] = function () {
  16891. options.apply_perm();
  16892. options.cleanup(false);
  16893. };
  16894. buttons[options.bCancel] = function () {
  16895. options.cleanup(true);
  16896. };
  16897. return $.extend(true, {
  16898. buttons: buttons,
  16899. close: function () {
  16900. options.cleanup(true);
  16901. },
  16902. modal: options.modal || false,
  16903. resizable: options.resizable || true,
  16904. width: options.width + 70,
  16905. resize: function () {
  16906. var widgetData = getMultiselectWidgetData(select),
  16907. $thisDialogContent = widgetData.container.closest(".ui-dialog-content");
  16908. if ($thisDialogContent.length > 0 && typeof $thisDialogContent[0].style === "object") {
  16909. $thisDialogContent[0].style.width = "";
  16910. } else {
  16911. $thisDialogContent.css("width", ""); // or just remove width style
  16912. }
  16913. widgetData.selectedList.height(Math.max(widgetData.selectedContainer.height() - widgetData.selectedActions.outerHeight() - 1, 1));
  16914. widgetData.availableList.height(Math.max(widgetData.availableContainer.height() - widgetData.availableActions.outerHeight() - 1, 1));
  16915. }
  16916. }, options.dialog_opts || {});
  16917. },
  16918. /* Function to get the permutation array, and pass it to the
  16919. "done" function */
  16920. apply_perm: function () {
  16921. var perm = new Array(p.colModel.length), i, gHead,
  16922. showHideColOptions = {
  16923. notSkipFrozen: opts.notSkipFrozen === undefined ? false : opts.notSkipFrozen,
  16924. skipSetGridWidth: true,
  16925. skipSetGroupHeaders: true
  16926. };
  16927. // we can use remapColumnsByName instead of remapColumns in general,
  16928. // but we try to hold the compatibility with old version. Thus we
  16929. // fill perm based on multiselectData.newColOrder
  16930. for (i = 0; i < p.colModel.length; i++) {
  16931. perm[i] = p.iColByName[multiselectData.newColOrder[i]];
  16932. }
  16933. $("option", select).each(function () {
  16934. if ($(this).is(":selected")) {
  16935. $self.jqGrid("showCol", colModel[this.value].name, showHideColOptions);
  16936. } else {
  16937. $self.jqGrid("hideCol", colModel[this.value].name, showHideColOptions);
  16938. }
  16939. });
  16940. if (opts.done) {
  16941. opts.done.call($self, perm);
  16942. }
  16943. if (p.groupHeader && (typeof p.groupHeader === "object" || $.isFunction(p.groupHeader))) {
  16944. $self.jqGrid("destroyGroupHeader", false);
  16945. p.groupHeader.groupHeaders = multiselectData.gh; // use modified groupHeader
  16946. if (p.pivotOptions != null && p.pivotOptions.colHeaders != null && p.pivotOptions.colHeaders.length > 1) {
  16947. gHead = p.pivotOptions.colHeaders;
  16948. for (i = 0; i < gHead.length; i++) {
  16949. // Multiple calls of setGroupHeaders for one grid are wrong,
  16950. // but there are produces good results in case of usage
  16951. // useColSpanStyle: false option. The rowspan values
  16952. // needed be increased in case of usage useColSpanStyle: true
  16953. if (gHead[i] && gHead[i].groupHeaders.length) {
  16954. $self.jqGrid("setGroupHeaders", gHead[i]);
  16955. }
  16956. }
  16957. } else {
  16958. $self.jqGrid("setGroupHeaders", p.groupHeader);
  16959. }
  16960. }
  16961. var newWidth = !p.autowidth && (p.widthOrg === undefined || p.widthOrg === "auto" || p.widthOrg === "100%") ? p.tblwidth : p.width;
  16962. if (newWidth !== p.width) {
  16963. $self.jqGrid("setGridWidth", newWidth, p.shrinkToFit);
  16964. }
  16965. },
  16966. /* Function to cleanup the dialog, and select. Also calls the
  16967. done function with no permutation (to indicate that the
  16968. columnChooser was aborted */
  16969. cleanup: function (calldone) {
  16970. call(opts.dlog, selector, "destroy");
  16971. call(opts.msel, select, "destroy");
  16972. selector.remove();
  16973. if (calldone && opts.done) {
  16974. opts.done.call($self);
  16975. }
  16976. },
  16977. msel_opts: {}
  16978. },
  16979. $self.jqGrid("getGridRes", "col"),
  16980. jgrid.col, opts || {});
  16981. if ($.ui) {
  16982. if ($UiMultiselect && $UiMultiselect.defaults) {
  16983. if (!jgrid._multiselect) {
  16984. // should be in language file
  16985. (jgrid.defaults != null && $.isFunction(jgrid.defaults.fatalError) ? jgrid.defaults.fatalError : alert)("Multiselect plugin loaded after jqGrid. Please load the plugin before the jqGrid!");
  16986. return;
  16987. }
  16988. // ??? the next line uses $.ui.multiselect.defaults which will be typically undefined
  16989. opts.msel_opts = $.extend($UiMultiselect.defaults, opts.msel_opts);
  16990. }
  16991. }
  16992. if (opts.caption) {
  16993. selector.attr("title", opts.caption);
  16994. }
  16995. if (opts.classname) {
  16996. selector.addClass(opts.classname);
  16997. select.addClass(opts.classname);
  16998. }
  16999. if (opts.width) {
  17000. $(">div", selector).css({ width: opts.width, margin: "0 auto" });
  17001. select.css("width", opts.width);
  17002. }
  17003. if (opts.height) {
  17004. $(">div", selector).css("height", opts.height);
  17005. select.css("height", opts.height - 10);
  17006. }
  17007. select.empty();
  17008. var gh = p.groupHeader != null ? p.groupHeader.groupHeaders : 0,
  17009. colHeader = {}, k, j, iCol, ghItem;
  17010. // fill colHeader for columns which have column header
  17011. if (gh) {
  17012. for (k = 0; k < gh.length; k++) {
  17013. ghItem = gh[k];
  17014. for (j = 0; j < ghItem.numberOfColumns; j++) {
  17015. iCol = p.iColByName[ghItem.startColumnName] + j;
  17016. colHeader[iCol] = $.isFunction(opts.buildItemText) ?
  17017. opts.buildItemText.call($self[0], {
  17018. iCol: iCol,
  17019. cm: colModel[iCol],
  17020. cmName: colModel[iCol].name,
  17021. colName: colNames[iCol],
  17022. groupTitleText: ghItem.titleText
  17023. }) :
  17024. $.jgrid.stripHtml(ghItem.titleText) + ": " +
  17025. $.jgrid.stripHtml(colNames[iCol] === "" ? colModel[iCol].name : colNames[iCol]);
  17026. }
  17027. }
  17028. }
  17029. // fill colHeader for all other columns
  17030. for (iCol = 0; iCol < nCol; iCol++) {
  17031. if (colHeader[iCol] === undefined) {
  17032. colHeader[iCol] = $.isFunction(opts.buildItemText) ?
  17033. opts.buildItemText.call($self[0], {
  17034. iCol: iCol,
  17035. cm: colModel[iCol],
  17036. cmName: colModel[iCol].name,
  17037. colName: colNames[iCol],
  17038. groupTitleText: null
  17039. }) :
  17040. $.jgrid.stripHtml(colNames[iCol]);
  17041. }
  17042. }
  17043. $.each(colModel, function (i) {
  17044. if (!this.hidedlg) {
  17045. select.append("<option value='" + i + "'" +
  17046. (p.headertitles || this.headerTitle ? (" title='" + jgrid.stripHtml(typeof this.headerTitle === "string" ? this.headerTitle : colHeader[i]) + "'") : "") +
  17047. (this.hidden ? "" : " selected='selected'") + ">" + colHeader[i] + "</option>");
  17048. }
  17049. });
  17050. dopts = $.isFunction(opts.dlog_opts) ? opts.dlog_opts.call($self, opts) : opts.dlog_opts;
  17051. call(opts.dlog, selector, dopts);
  17052. mopts = $.isFunction(opts.msel_opts) ? opts.msel_opts.call($self, opts) : opts.msel_opts;
  17053. call(opts.msel, select, mopts);
  17054. // fix height of elements of the multiselect widget
  17055. $dialogContent = $("#colchooser_" + jqID(p.id));
  17056. $dialogContent.css({ margin: "auto" });
  17057. $dialogContent.find(">div").css({ width: "100%", height: "100%", margin: "auto" });
  17058. multiselectData = getMultiselectWidgetData(select);
  17059. if (multiselectData) {
  17060. // grid property will be used to access the grid inside of _setSelected
  17061. multiselectData.grid = self;
  17062. if (gh) {
  17063. // make deep copy of groupHeaders to be able to hold changes of startColumnName,
  17064. // but to apply the changes only after the user click OK button (not Cancel)
  17065. multiselectData.gh = $.extend(true, [], gh);
  17066. // filling the helper array inGroup. It contains
  17067. // an item for every column. The value is undefined if the column
  17068. // not belongs to a header group and it is 0-based index of the
  17069. // header group (the index in gh array) if the column belongs to
  17070. // a header group. The array inGroup helps us to detect whether
  17071. // two columns belong to the same group or not.
  17072. multiselectData.inGroup = new Array(p.colModel.length); // allocate array with undefined values
  17073. var iGrp, headerItem;
  17074. for (iGrp = 0; iGrp < gh.length; iGrp++) {
  17075. headerItem = gh[iGrp];
  17076. for (iCol = 0; iCol < headerItem.numberOfColumns; iCol++) {
  17077. multiselectData.inGroup[p.iColByName[headerItem.startColumnName] + iCol] = iGrp;
  17078. }
  17079. }
  17080. }
  17081. multiselectData.newColOrder = $.map(colModel, function (cm) { return cm.name; });
  17082. multiselectData.container.css({ width: "100%", height: "100%", margin: "auto" });
  17083. multiselectData.selectedContainer.css({ width: multiselectData.options.dividerLocation * 100 + "%", height: "100%", margin: "auto", boxSizing: "border-box" });
  17084. multiselectData.availableContainer.css({ width: (100 - multiselectData.options.dividerLocation * 100) + "%", height: "100%", margin: "auto", boxSizing: "border-box" });
  17085. // set height for both selectedList and availableList
  17086. multiselectData.selectedList.css("height", "auto");
  17087. multiselectData.availableList.css("height", "auto");
  17088. listHeight = Math.max(multiselectData.selectedList.height(), multiselectData.availableList.height());
  17089. listHeight = Math.min(listHeight, $(window).height());
  17090. multiselectData.selectedList.css("height", listHeight);
  17091. multiselectData.availableList.css("height", listHeight);
  17092. if (multiselectData.options != null && multiselectData.options.sortable) {
  17093. multiselectData.selectedList.on("sortupdate", function (e, ui) {
  17094. // remove fixed inline style values of width and height
  17095. // added during gragging
  17096. reorderSelectedColumns.call(
  17097. multiselectData,
  17098. parseInt(ui.item.data("optionLink").val(), 10)
  17099. );
  17100. ui.item.css({ width: "", height: "" });
  17101. if ($.isFunction(opts.sortUpdate)) {
  17102. opts.sortUpdate.call(self, e, ui);
  17103. }
  17104. });
  17105. }
  17106. if ($.isFunction(opts.init)) {
  17107. opts.init.call(self, multiselectData);
  17108. }
  17109. }
  17110. },
  17111. sortableRows: function (opts) {
  17112. // Can accept all sortable options and events
  17113. return this.each(function () {
  17114. var $t = this, grid = $t.grid, p = $t.p;
  17115. if (!grid) { return; }
  17116. // Currently we disable a treeGrid sortable
  17117. if (p.treeGrid) { return; }
  17118. if ($.fn.sortable) {
  17119. opts = $.extend({
  17120. cursor: "move",
  17121. axis: "y",
  17122. items: ">tbody>.jqgrow"
  17123. },
  17124. opts || {});
  17125. if (opts.start && $.isFunction(opts.start)) {
  17126. opts._start_ = opts.start;
  17127. delete opts.start;
  17128. } else { opts._start_ = false; }
  17129. if (opts.update && $.isFunction(opts.update)) {
  17130. opts._update_ = opts.update;
  17131. delete opts.update;
  17132. } else { opts._update_ = false; }
  17133. opts.start = function (ev, ui) {
  17134. $(ui.item).css("border-width", "0");
  17135. $("td", ui.item).each(function (i) {
  17136. this.style.width = grid.cols[i].style.width;
  17137. });
  17138. if (p.subGrid) {
  17139. var subgid = $(ui.item).attr("id");
  17140. try {
  17141. $($t).jqGrid("collapseSubGridRow", subgid);
  17142. } catch (ignore) { }
  17143. }
  17144. if (opts._start_) {
  17145. opts._start_.apply(this, [ev, ui]);
  17146. }
  17147. };
  17148. opts.update = function (ev, ui) {
  17149. $(ui.item).css("border-width", "");
  17150. if (p.rownumbers === true) {
  17151. $("td.jqgrid-rownum", $t.rows).each(function (i) {
  17152. $(this).html(i + 1 + (parseInt(p.page, 10) - 1) * parseInt(p.rowNum, 10));
  17153. });
  17154. }
  17155. if (opts._update_) {
  17156. opts._update_.apply(this, [ev, ui]);
  17157. }
  17158. };
  17159. $($t).sortable(opts);
  17160. /*if ($.isFunction($.fn.disableSelection)) {
  17161. // The method disableSelection exists starting with jQuery UI 1.6,
  17162. // but it's declared as deprecated since jQuery UI 1.9
  17163. // see http://jqueryui.com/upgrade-guide/1.9/#deprecated-disableselection-and-enableselection
  17164. // so we use disableSelection only if it exists
  17165. var jQueryUiVersion = $.ui != null && typeof $.ui.version === "string" ?
  17166. $.ui.version.match(/(\d+)\.(\d+).(\d+)/) : [];
  17167. // jQuery UI version is: jQueryUiVersion[1].jQueryUiVersion[2].jQueryUiVersion[3]
  17168. if (jQueryUiVersion.length === 4 && jQueryUiVersion[1] === "1" &&
  17169. jQueryUiVersion[2] > 5 && jQueryUiVersion[2] < 9) {
  17170. // disable selection only for old jQuery UI
  17171. $($t.tBodies[0]).children("tr.jqgrow").disableSelection();
  17172. }
  17173. }*/
  17174. }
  17175. });
  17176. },
  17177. gridDnD: function (opts) {
  17178. return this.each(function () {
  17179. var $t = this, j, cn;
  17180. if (!$t.grid) { return; }
  17181. // Currently we disable a treeGrid drag and drop
  17182. if ($t.p.treeGrid) { return; }
  17183. if (!$.fn.draggable || !$.fn.droppable) { return; }
  17184. function updateDnD() {
  17185. var datadnd = $.data($t, "dnd");
  17186. $("tr.jqgrow:not(.ui-draggable)", $t).draggable($.isFunction(datadnd.drag) ? datadnd.drag.call($($t), datadnd) : datadnd.drag);
  17187. }
  17188. var appender = "<table id='jqgrid_dnd' class='ui-jqgrid-dnd'></table>";
  17189. if ($("#jqgrid_dnd")[0] === undefined) {
  17190. $("body").append(appender);
  17191. }
  17192. if (typeof opts === "string" && opts === "updateDnD" && $t.p.jqgdnd === true) {
  17193. updateDnD();
  17194. return;
  17195. }
  17196. opts = $.extend({
  17197. drag: function (opts1) {
  17198. return $.extend({
  17199. start: function (ev, ui) {
  17200. var i, subgid;
  17201. // if we are in subgrid mode try to collapse the node
  17202. if ($t.p.subGrid) {
  17203. subgid = $(ui.helper).attr("id");
  17204. try {
  17205. $($t).jqGrid("collapseSubGridRow", subgid);
  17206. } catch (ignore) { }
  17207. }
  17208. // hack
  17209. // drag and drop does not insert tr in table, when the table has no rows
  17210. // we try to insert new empty row on the target(s)
  17211. for (i = 0; i < $.data($t, "dnd").connectWith.length; i++) {
  17212. if ($($.data($t, "dnd").connectWith[i]).jqGrid("getGridParam", "reccount") === 0) {
  17213. $($.data($t, "dnd").connectWith[i]).jqGrid("addRowData", "jqg_empty_row", {});
  17214. }
  17215. }
  17216. ui.helper.addClass("ui-state-highlight");
  17217. $("td", ui.helper).each(function (iCol) {
  17218. this.style.width = $t.grid.headers[iCol].width + "px";
  17219. });
  17220. if (opts1.onstart && $.isFunction(opts1.onstart)) { opts1.onstart.call($($t), ev, ui); }
  17221. },
  17222. stop: function (ev, ui) {
  17223. var i, ids;
  17224. if (ui.helper.dropped && !opts1.dragcopy) {
  17225. ids = $(ui.helper).attr("id");
  17226. if (ids === undefined) { ids = $(this).attr("id"); }
  17227. $($t).jqGrid("delRowData", ids);
  17228. }
  17229. // if we have a empty row inserted from start event try to delete it
  17230. for (i = 0; i < $.data($t, "dnd").connectWith.length; i++) {
  17231. $($.data($t, "dnd").connectWith[i]).jqGrid("delRowData", "jqg_empty_row");
  17232. }
  17233. if (opts1.onstop && $.isFunction(opts1.onstop)) { opts1.onstop.call($($t), ev, ui); }
  17234. }
  17235. }, opts1.drag_opts || {});
  17236. },
  17237. drop: function (opts1) {
  17238. return $.extend({
  17239. accept: function (d) {
  17240. if (!$(d).hasClass("jqgrow")) { return d; }
  17241. var tid = $(d).closest("table.ui-jqgrid-btable");
  17242. if (tid.length > 0 && $.data(tid[0], "dnd") !== undefined) {
  17243. var cn1 = $.data(tid[0], "dnd").connectWith;
  17244. return $.inArray("#" + jqID(this.id), cn1) !== -1 ? true : false;
  17245. }
  17246. return false;
  17247. },
  17248. drop: function (ev, ui) {
  17249. if (!$(ui.draggable).hasClass("jqgrow")) { return; }
  17250. var rowid = $(ui.draggable).attr("id"),
  17251. $srcGrid = ui.draggable.parent().parent(),
  17252. getdata = $srcGrid.jqGrid("getRowData", rowid);
  17253. if (!opts1.dropbyname) {
  17254. var tmpdata = {}, iSrc, iDest, srcName, destName,
  17255. srcColModel = $srcGrid.jqGrid("getGridParam", "colModel"),
  17256. destColModel = $("#" + jqID(this.id)).jqGrid("getGridParam", "colModel");
  17257. try {
  17258. for (iSrc = 0, iDest = 0; iSrc < srcColModel.length && iDest < destColModel.length; iSrc++) {
  17259. srcName = srcColModel[iSrc].name;
  17260. if (!(srcName === "cb" || srcName === "rn" || srcName === "subgrid")) {
  17261. // src column found, which need be copied
  17262. for (; iDest < destColModel.length; iDest++) {
  17263. destName = destColModel[iDest].name;
  17264. if (!(destName === "cb" || destName === "rn" || destName === "subgrid")) {
  17265. tmpdata[destName] = getdata[srcName];
  17266. break;
  17267. }
  17268. }
  17269. iDest++;
  17270. }
  17271. }
  17272. getdata = tmpdata;
  17273. } catch (ignore) { }
  17274. }
  17275. ui.helper.dropped = true;
  17276. if (opts1.beforedrop && $.isFunction(opts1.beforedrop)) {
  17277. //parameters to this callback - event, element, data to be inserted, sender, reciever
  17278. // should return object which will be inserted into the reciever
  17279. var datatoinsert = opts1.beforedrop.call(this, ev, ui, getdata, $("#" + jqID($t.p.id)), $(this));
  17280. if (datatoinsert !== undefined && datatoinsert !== null && typeof datatoinsert === "object") { getdata = datatoinsert; }
  17281. }
  17282. if (ui.helper.dropped) {
  17283. var grid;
  17284. if (opts1.autoid) {
  17285. if ($.isFunction(opts1.autoid)) {
  17286. grid = opts1.autoid.call(this, getdata, {
  17287. rowid: rowid,
  17288. ev: ev,
  17289. ui: ui
  17290. });
  17291. } else {
  17292. grid = Math.ceil(Math.random() * 1000);
  17293. grid = opts1.autoidprefix + grid;
  17294. }
  17295. }
  17296. // NULL is interpreted as undefined while null as object
  17297. $("#" + jqID(this.id)).jqGrid("addRowData", grid, getdata, opts1.droppos);
  17298. getdata[$t.p.localReader.id] = grid;
  17299. }
  17300. if (opts1.ondrop && $.isFunction(opts1.ondrop)) { opts1.ondrop.call(this, ev, ui, getdata); }
  17301. }
  17302. }, opts1.drop_opts || {});
  17303. },
  17304. onstart: null,
  17305. onstop: null,
  17306. beforedrop: null,
  17307. ondrop: null,
  17308. drop_opts: {
  17309. //activeClass: "ui-state-active",
  17310. //hoverClass: "ui-state-hover"
  17311. },
  17312. drag_opts: {
  17313. revert: "invalid",
  17314. helper: "clone",
  17315. cursor: "move",
  17316. appendTo: "#jqgrid_dnd",
  17317. zIndex: 5000
  17318. },
  17319. dragcopy: false,
  17320. dropbyname: false,
  17321. droppos: "first",
  17322. autoid: true,
  17323. autoidprefix: "dnd_"
  17324. }, opts || {});
  17325. if (!opts.connectWith) { return; }
  17326. opts.connectWith = opts.connectWith.split(",");
  17327. opts.connectWith = $.map(opts.connectWith, function (n) { return $.trim(n); });
  17328. $.data($t, "dnd", opts);
  17329. if ($t.p.reccount !== 0 && !$t.p.jqgdnd) {
  17330. updateDnD();
  17331. }
  17332. $t.p.jqgdnd = true;
  17333. for (j = 0; j < opts.connectWith.length; j++) {
  17334. cn = opts.connectWith[j];
  17335. $(cn).droppable($.isFunction(opts.drop) ? opts.drop.call($($t), opts) : opts.drop);
  17336. }
  17337. });
  17338. },
  17339. gridResize: function (opts) {
  17340. return this.each(function () {
  17341. var $t = this, grid = $t.grid, p = $t.p, bdivSelector = p.gView + ">.ui-jqgrid-bdiv", onlyHorizontal = false, sel, gridHeight = p.height;
  17342. if (!grid || !$.fn.resizable) { return; }
  17343. opts = $.extend({}, opts || {});
  17344. if (opts.alsoResize) {
  17345. opts._alsoResize_ = opts.alsoResize;
  17346. delete opts.alsoResize;
  17347. } else {
  17348. opts._alsoResize_ = false;
  17349. }
  17350. if (opts.stop && $.isFunction(opts.stop)) {
  17351. opts._stop_ = opts.stop;
  17352. delete opts.stop;
  17353. } else {
  17354. opts._stop_ = false;
  17355. }
  17356. opts.stop = function (ev, ui) {
  17357. $($t).jqGrid("setGridWidth", ui.size.width, opts.shrinkToFit);
  17358. $(p.gView + ">.ui-jqgrid-titlebar").css("width", "");
  17359. if (!onlyHorizontal) {
  17360. $($t).jqGrid("setGridParam", { height: $(bdivSelector).height() });
  17361. } else {
  17362. $(sel).each(function () {
  17363. $(this).css("height", "");
  17364. });
  17365. if (gridHeight === "auto" || gridHeight === "100%") {
  17366. $(grid.bDiv).css("height", gridHeight);
  17367. }
  17368. }
  17369. if ($t.fixScrollOffsetAndhBoxPadding) {
  17370. $t.fixScrollOffsetAndhBoxPadding();
  17371. }
  17372. if (opts._stop_) { opts._stop_.call($t, ev, ui); }
  17373. };
  17374. sel = bdivSelector;
  17375. if ((gridHeight === "auto" || gridHeight === "100%") && opts.handles === undefined) {
  17376. opts.handles = "e,w";
  17377. }
  17378. if (opts.handles) {
  17379. // test for "e, w"
  17380. var ar = $.map(String(opts.handles).split(","), function (item) {
  17381. return $.trim(item);
  17382. });
  17383. if (ar.length === 2 && ((ar[0] === "e" && ar[1] === "w") || (ar[1] === "e" && ar[1] === "w"))) {
  17384. sel = p.gView + ">div:not(.frozen-div)";
  17385. onlyHorizontal = true;
  17386. if (p.pager) {
  17387. sel += "," + p.pager;
  17388. }
  17389. }
  17390. }
  17391. if (opts._alsoResize_) {
  17392. opts.alsoResize = sel + "," + opts._alsoResize_;
  17393. } else {
  17394. opts.alsoResize = sel;
  17395. }
  17396. delete opts._alsoResize_;
  17397. $(p.gBox).resizable(opts);
  17398. });
  17399. }
  17400. });
  17401. // end module grid.jqueryui
  17402. /**
  17403. * jqGrid pivot functions
  17404. * Copyright (c) 2008-2014, Tony Tomov, tony@trirand.com, http://trirand.com/blog/
  17405. * Copyright (c) 2014-2018, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  17406. * The modul is created initially by Tony Tomov and it's full rewritten
  17407. * for free jqGrid: https://github.com/free-jqgrid/jqGrid by Oleg Kiriljuk
  17408. * Dual licensed under the MIT and GPL licenses:
  17409. * http://www.opensource.org/licenses/mit-license.php
  17410. * http://www.gnu.org/licenses/gpl-2.0.html
  17411. */
  17412. // begin module grid.pivot
  17413. function Aggregation(aggregator, context, pivotOptions) {
  17414. if (!(this instanceof Aggregation)) {
  17415. return new Aggregation(aggregator);
  17416. }
  17417. //this.result = undefined;
  17418. //this.count = undefined;
  17419. this.aggregator = aggregator;
  17420. this.finilized = false;
  17421. this.context = context;
  17422. this.pivotOptions = pivotOptions;
  17423. }
  17424. Aggregation.prototype.calc = function (v, fieldName, row, iRow, rows) {
  17425. var self = this;
  17426. if (v !== undefined) {
  17427. self.result = self.result || 0; // change undefined to 0
  17428. v = parseFloat(v);
  17429. switch (self.aggregator) {
  17430. case "sum":
  17431. self.result += v;
  17432. break;
  17433. case "count":
  17434. self.result++;
  17435. break;
  17436. case "avg":
  17437. if (self.finilized) {
  17438. self.count = self.count || 0; // change undefined to 0
  17439. self.result = (self.result * self.count + v) / (self.count + 1);
  17440. self.count++;
  17441. } else {
  17442. self.result += v;
  17443. self.count = self.count || 0; // change undefined to 0
  17444. self.count++;
  17445. }
  17446. break;
  17447. case "min":
  17448. self.result = Math.min(self.result, v);
  17449. break;
  17450. case "max":
  17451. self.result = Math.max(self.result, v);
  17452. break;
  17453. default:
  17454. if ($.isFunction(self.aggregator)) {
  17455. self.result = self.aggregator.call(self.context, {
  17456. previousResult: self.result,
  17457. value: v,
  17458. fieldName: fieldName,
  17459. item: row,
  17460. iItem: iRow,
  17461. items: rows
  17462. });
  17463. }
  17464. break;
  17465. }
  17466. }
  17467. };
  17468. Aggregation.prototype.getResult = function (obj, propName, forceSaving) {
  17469. var self = this;
  17470. if (self.result !== undefined || forceSaving) {
  17471. if (forceSaving) {
  17472. if (self.result !== undefined) {
  17473. self.result = 0;
  17474. self.count = 0;
  17475. }
  17476. }
  17477. if (self.result !== undefined && !self.finilized && self.aggregator === "avg") {
  17478. self.result = self.result / self.count;
  17479. self.finilized = true;
  17480. }
  17481. obj[propName] = self.result;
  17482. }
  17483. };
  17484. function ArrayOfFieldsets(trimByCollect, caseSensitive, skipSort, dimension, fieldName) {
  17485. var iField, dimensionLength = dimension.length, dimensionItem, self = this,
  17486. stringCompare = function (a, b) {
  17487. var a1 = a, b1 = b;
  17488. if (a1 == null) { a1 = ""; } // we will place undefined and null values as the lowest TOGETHER with ""
  17489. if (b1 == null) { b1 = ""; }
  17490. // be sure that we have no other input data (Number, Date and so on)
  17491. a1 = String(a1);
  17492. b1 = String(b1);
  17493. if (!this.caseSensitive) {
  17494. a1 = a1.toUpperCase();
  17495. b1 = b1.toUpperCase();
  17496. }
  17497. if (a1 === b1) {
  17498. if (a === b) {//typeof a === typeof b) {
  17499. return 0;
  17500. }
  17501. // either a or b is undefined or null
  17502. if (a === undefined) { return -1; } // make undefined less as all other
  17503. if (b === undefined) { return 1; }
  17504. if (a === null) { return -1; } // make null less as all other with the exception undefined
  17505. if (b === null) { return 1; }
  17506. }
  17507. if (a1 < b1) {
  17508. return -1;
  17509. }
  17510. return 1;
  17511. },
  17512. numberCompare = function (a, b) {
  17513. a = Number(a);
  17514. b = Number(b);
  17515. if (a === b) {
  17516. return 0;
  17517. }
  17518. if (a < b) {
  17519. return -1;
  17520. }
  17521. return 1;
  17522. },
  17523. integerCompare = function (a, b) {
  17524. a = Math.floor(Number(a));
  17525. b = Math.floor(Number(b));
  17526. if (a === b) {
  17527. return 0;
  17528. }
  17529. if (a < b) {
  17530. return -1;
  17531. }
  17532. return 1;
  17533. };
  17534. self.items = [];
  17535. self.indexesOfSourceData = [];
  17536. self.trimByCollect = trimByCollect;
  17537. self.caseSensitive = caseSensitive;
  17538. self.skipSort = skipSort;
  17539. self.fieldLength = dimensionLength;
  17540. self.fieldNames = new Array(dimensionLength);
  17541. self.fieldSortDirection = new Array(dimensionLength);
  17542. self.fieldCompare = new Array(dimensionLength); // 0 - number, 1 - integer, 2 - string, one can extend for Date and other
  17543. for (iField = 0; iField < dimensionLength; iField++) {
  17544. dimensionItem = dimension[iField];
  17545. self.fieldNames[iField] = dimensionItem[fieldName || "dataName"];
  17546. switch (dimensionItem.sorttype) {
  17547. case "integer":
  17548. case "int":
  17549. self.fieldCompare[iField] = integerCompare;
  17550. break;
  17551. case "number":
  17552. case "currency":
  17553. case "float":
  17554. self.fieldCompare[iField] = numberCompare;
  17555. break;
  17556. default:
  17557. self.fieldCompare[iField] = $.isFunction(dimensionItem.compare) ? dimensionItem.compare : stringCompare;
  17558. break;
  17559. }
  17560. self.fieldSortDirection[iField] = dimensionItem.sortorder === "desc" ? -1 : 1;
  17561. }
  17562. }
  17563. ArrayOfFieldsets.prototype.compareVectorsEx = function (vector1, vector2) {
  17564. var self = this, fieldLength = self.fieldLength, iField, compareResult;
  17565. for (iField = 0; iField < fieldLength; iField++) {
  17566. compareResult = self.fieldCompare[iField](vector1[iField], vector2[iField]);
  17567. if (compareResult !== 0) {
  17568. return {
  17569. index: iField,
  17570. result: compareResult
  17571. };
  17572. }
  17573. }
  17574. return {
  17575. index: -1,
  17576. result: 0
  17577. };
  17578. };
  17579. ArrayOfFieldsets.prototype.getIndexOfDifferences = function (vector1, vector2) {
  17580. if (vector2 === null || vector1 === null) {
  17581. return 0;
  17582. }
  17583. return this.compareVectorsEx(vector1, vector2).index;
  17584. };
  17585. ArrayOfFieldsets.prototype.compareVectors = function (vector1, vector2) {
  17586. var compareRestlts = this.compareVectorsEx(vector1, vector2),
  17587. sortDirection = compareRestlts.index >= 0 ? this.fieldSortDirection[compareRestlts.index] : 1;
  17588. return sortDirection > 0 ? compareRestlts.result : -compareRestlts.result;
  17589. };
  17590. ArrayOfFieldsets.prototype.getItem = function (index) {
  17591. return this.items[index];
  17592. };
  17593. ArrayOfFieldsets.prototype.getIndexLength = function () {
  17594. return this.items.length;
  17595. };
  17596. ArrayOfFieldsets.prototype.getIndexesOfSourceData = function (index) {
  17597. return this.indexesOfSourceData[index];
  17598. };
  17599. ArrayOfFieldsets.prototype.createDataIndex = function (data) {
  17600. var self = this, iRow, nRows = data.length, fieldLength = self.fieldLength, values, v,
  17601. fieldNames = self.fieldNames, indexesOfSourceData = self.indexesOfSourceData, iField, compareResult, i, item,
  17602. items = self.items, iMin, iMax;
  17603. for (iRow = 0; iRow < nRows; iRow++) {
  17604. item = data[iRow];
  17605. // build the set of fields with data of the current item
  17606. values = new Array(fieldLength);
  17607. for (iField = 0; iField < fieldLength; iField++) {
  17608. v = item[fieldNames[iField]];
  17609. if (v !== undefined) {
  17610. if (typeof v === "string" && self.trimByCollect) {
  17611. v = $.trim(v);
  17612. }
  17613. values[iField] = v;
  17614. }
  17615. }
  17616. // compare values with items having index iMax and iMin
  17617. // If we use skipSort:true option then we compare always
  17618. // with iMax item only.
  17619. iMin = 0;
  17620. iMax = items.length - 1;
  17621. if (iMax < 0) {
  17622. items.push(values);
  17623. indexesOfSourceData.push([iRow]);
  17624. continue;
  17625. }
  17626. compareResult = self.compareVectors(values, items[iMax]);
  17627. if (compareResult === 0) {
  17628. indexesOfSourceData[iMax].push(iRow);
  17629. continue;
  17630. }
  17631. if (compareResult === 1 || self.skipSort) {
  17632. // in case of the empty array this.items or if the values is larger as the
  17633. // the max (last) element of this.items: append values to the array this.items
  17634. items.push(values);
  17635. indexesOfSourceData.push([iRow]);
  17636. continue;
  17637. }
  17638. compareResult = self.compareVectors(items[0], values);
  17639. if (compareResult === 1) {
  17640. // if the min (first) element values is larger as the values:
  17641. // insert the values as the first element of the array this.items
  17642. items.unshift(values);
  17643. indexesOfSourceData.unshift([iRow]);
  17644. continue;
  17645. }
  17646. if (compareResult === 0) {
  17647. indexesOfSourceData[0].push(iRow);
  17648. continue;
  17649. }
  17650. // we are sure that items[iMin] < values < items[iMax]
  17651. while (true) {
  17652. if (iMax - iMin < 2) {
  17653. // no identical items are found we need to insert the item at i index
  17654. items.splice(iMax, 0, values); // insert after iMin
  17655. indexesOfSourceData.splice(iMax, 0, [iRow]);
  17656. break;
  17657. }
  17658. i = Math.floor((iMin + iMax) / 2); // | 0 means Math.floor, but it's faster sometimes.
  17659. compareResult = self.compareVectors(items[i], values);
  17660. if (compareResult === 0) {
  17661. indexesOfSourceData[i].push(iRow);
  17662. break;
  17663. }
  17664. if (compareResult === 1) {
  17665. iMax = i;
  17666. } else {
  17667. iMin = i;
  17668. }
  17669. }
  17670. }
  17671. };
  17672. jgrid.extend({
  17673. pivotSetup: function (data, options) {
  17674. // data should come in json format
  17675. // The function return the new colModel and the transformed data
  17676. // again with group setup options which then will be passed to the grid
  17677. var self = this[0], isArray = $.isArray, summaries = {},
  17678. groupingView = {
  17679. groupField: [],
  17680. groupSummary: [],
  17681. groupSummaryPos: []
  17682. },
  17683. groupOptions = {
  17684. grouping: true,
  17685. groupingView: groupingView
  17686. },
  17687. o = $.extend({
  17688. totals: false, // replacement for rowTotals. totalText and totalHeader can be used additionally
  17689. useColSpanStyle: false,
  17690. trimByCollect: true,
  17691. skipSortByX: false,
  17692. skipSortByY: false,
  17693. caseSensitive: false,
  17694. footerTotals: false, // replacement colTotals. footerAggregator option and totalText properties of xDimension[i] can be used additionally
  17695. groupSummary: true,
  17696. groupSummaryPos: "header",
  17697. frozenStaticCols: false,
  17698. defaultFormatting: true,
  17699. data: data
  17700. }, options || {}),
  17701. row, i, k, nRows = data.length, x, y, cm, iRow, cmName, iXData, itemXData, pivotInfos, rows,
  17702. xDimension = o.xDimension, yDimension = o.yDimension, aggregates = o.aggregates, aggrContext,
  17703. isRowTotal = o.totalText || o.totals || o.rowTotals || o.totalHeader, aggrTotal, gi,
  17704. xlen = isArray(xDimension) ? xDimension.length : 0,
  17705. ylen = isArray(yDimension) ? yDimension.length : 0,
  17706. aggrlen = isArray(aggregates) ? aggregates.length : 0,
  17707. headerLevels = ylen - (aggrlen === 1 ? 1 : 0),
  17708. colHeaders = [], hasGroupTotal = [], colModel = [], outputItems = [],
  17709. additionalProperties = ["pivotInfos"],
  17710. aggrContextTotalRows = new Array(aggrlen), aggrContextGroupTotalRows = new Array(ylen),
  17711. xIndexLength, indexesOfDataWithTheSameXValues, iYData, itemYData, indexesOfDataWithTheSameYValues,
  17712. iRows, agr, outputItem, previousY, groupHeaders, iRowsY, xIndex, yIndex, yIndexLength,
  17713. indexDataBy = function (dimension, skipSort, compareVectors) {
  17714. var index = new ArrayOfFieldsets(o.trimByCollect, o.caseSensitive, skipSort, dimension);
  17715. if ($.isFunction(compareVectors)) {
  17716. index.compareVectorsEx = compareVectors;
  17717. }
  17718. index.createDataIndex(data);
  17719. return index;
  17720. },
  17721. buildColModelItem = function (colType, agr1, iAggr, level, iyData) {
  17722. var label, name, cmItem;
  17723. switch (colType) {
  17724. case 1: // total group
  17725. label = yDimension[level].totalText || "{0} {1} {2}";
  17726. name = "y" + iyData + "t" + level;
  17727. break;
  17728. case 2: // grand total
  17729. label = o.totalText || "{0}";
  17730. name = "t";
  17731. break;
  17732. //case 0: // standard column
  17733. default:
  17734. label = aggrlen > 1 ?
  17735. agr1.label || "{0}" :
  17736. ($.isFunction(yDimension[level].label) ?
  17737. yDimension[level].label :
  17738. yIndex.getItem(iyData)[level]);
  17739. name = "y" + iyData;
  17740. break;
  17741. }
  17742. cmItem = $.extend({}, agr1, {
  17743. name: name + (aggrlen > 1 ? "a" + iAggr : ""),
  17744. label: $.isFunction(label) ?
  17745. (label.call(self, colType === 2 ?
  17746. { aggregate: agr1, iAggregate: iAggr, pivotOptions: o } :
  17747. (colType === 1 ?
  17748. { yIndex: yIndex.getItem(iyData), aggregate: agr1, iAggregate: iAggr, yLevel: level, pivotOptions: o } :
  17749. { yData: yIndex.getItem(iyData)[level], yIndex: yIndex.getItem(iyData), yLevel: level, pivotOptions: o }))) :
  17750. (jgrid.template.apply(self, colType === 2 ?
  17751. [String(label), agr1.aggregator, agr1.member, iAggr] :
  17752. [String(label), agr1.aggregator, agr1.member, yIndex.getItem(iyData)[level], level]))
  17753. });
  17754. delete cmItem.member;
  17755. delete cmItem.aggregator;
  17756. return cmItem;
  17757. },
  17758. addColumnToColModel = function (colType, level, iyData) {
  17759. var iAggr, aggregate;
  17760. for (iAggr = 0; iAggr < aggrlen; iAggr++) {
  17761. aggregate = aggregates[iAggr];
  17762. if (aggregate.template === undefined && aggregate.formatter === undefined && o.defaultFormatting) {
  17763. aggregate.template = aggregate.aggregator === "count" ? "integer" : "number";
  17764. }
  17765. colModel.push(buildColModelItem(colType, aggregate, iAggr, level, iyData));
  17766. }
  17767. },
  17768. addGroupTotalHeaders = function (iyData, level, previousY1) {
  17769. var iLevel, j, totalHeader, headerOnTop;
  17770. for (iLevel = headerLevels - 1; iLevel >= level; iLevel--) {
  17771. if (hasGroupTotal[iLevel]) {
  17772. for (j = 0; j <= iLevel; j++) {
  17773. groupHeaders = colHeaders[j].groupHeaders;
  17774. groupHeaders[groupHeaders.length - 1].numberOfColumns += aggrlen;
  17775. }
  17776. y = yDimension[iLevel];
  17777. totalHeader = y.totalHeader;
  17778. headerOnTop = y.headerOnTop;
  17779. for (j = iLevel + 1; j <= headerLevels - 1; j++) {
  17780. colHeaders[j].groupHeaders.push({
  17781. titleText: ((headerOnTop && j === iLevel + 1) || (!headerOnTop && j === headerLevels - 1)) ?
  17782. ($.isFunction(totalHeader) ?
  17783. totalHeader.call(self, previousY1, iLevel) :
  17784. jgrid.template.call(self, String(totalHeader || ""), previousY1[iLevel], iLevel)) :
  17785. "",
  17786. startColumnName: "y" + (iyData - 1) + "t" + iLevel + (aggrlen === 1 ? "" : "a0"),
  17787. numberOfColumns: aggrlen
  17788. });
  17789. }
  17790. }
  17791. }
  17792. },
  17793. createTotalAggregation = function (iAggr) {
  17794. var aggrGroup = new Aggregation(aggregates[iAggr].aggregator === "count" ? "sum" : aggregates[iAggr].aggregator, self, options);
  17795. aggrGroup.groupInfo = { iRows: [], rows: [], ys: [], iYs: [] };
  17796. return aggrGroup;
  17797. },
  17798. initializeGroupTotals = function () {
  17799. var iLevel, iAggr;
  17800. for (iLevel = headerLevels - 1; iLevel >= 0; iLevel--) {
  17801. if (hasGroupTotal[iLevel]) {
  17802. if (aggrContextGroupTotalRows[iLevel] == null) {// first call
  17803. aggrContextGroupTotalRows[iLevel] = new Array(aggrlen);
  17804. }
  17805. for (iAggr = 0; iAggr < aggrlen; iAggr++) {
  17806. aggrContextGroupTotalRows[iLevel][iAggr] = createTotalAggregation(iAggr);
  17807. }
  17808. }
  17809. }
  17810. },
  17811. finalizeGroupTotals = function (iyData, itemYData1, previousY1, iAggr) {
  17812. var iLevel, level = yIndex.getIndexOfDifferences(itemYData1, previousY1), fieldName, aggrGroup;
  17813. if (previousY1 !== null) {
  17814. // test whether the group is finished and one need to get results
  17815. level = Math.max(level, 0); // change -1 to 0 for the last call (itemYData === previousY)
  17816. for (iLevel = headerLevels - 1; iLevel >= level; iLevel--) {
  17817. fieldName = "y" + iyData + "t" + iLevel + (aggrlen > 1 ? "a" + iAggr : "");
  17818. if (hasGroupTotal[iLevel] && outputItem[fieldName] === undefined) {
  17819. aggrGroup = aggrContextGroupTotalRows[iLevel][iAggr];
  17820. aggrGroup.getResult(outputItem, fieldName);
  17821. outputItem.pivotInfos[fieldName] = {
  17822. colType: 1,
  17823. iA: iAggr,
  17824. a: aggregates[iAggr],
  17825. level: iLevel,
  17826. iRows: aggrGroup.groupInfo.iRows,
  17827. rows: aggrGroup.groupInfo.rows,
  17828. ys: aggrGroup.groupInfo.ys,
  17829. iYs: aggrGroup.groupInfo.iYs
  17830. };
  17831. if (itemYData1 !== previousY1) {
  17832. aggrContextGroupTotalRows[iLevel][iAggr] = createTotalAggregation(iAggr);
  17833. }
  17834. }
  17835. }
  17836. }
  17837. },
  17838. calculateGroupTotals = function (itemYData1, previousY1, aggregate, iAggr, row1, iRow1, iyData) {
  17839. // the method will be called at the first time with previousY === null in every output row
  17840. // and finally with itemYData === previousY for getting results of all aggregation contexts
  17841. var iLevel, aggrGroup, groupInfo;
  17842. if (itemYData1 !== previousY1) { // not the last call in the row
  17843. for (iLevel = headerLevels - 1; iLevel >= 0; iLevel--) {
  17844. if (hasGroupTotal[iLevel]) {
  17845. aggrGroup = aggrContextGroupTotalRows[iLevel][iAggr];
  17846. aggrGroup.calc(row1[aggregate.member], aggregate.member, row1, iRow1, data);
  17847. groupInfo = aggrGroup.groupInfo;
  17848. if ($.inArray(iyData, groupInfo.iYs) < 0) {
  17849. groupInfo.iYs.push(iyData);
  17850. groupInfo.ys.push(itemYData1);
  17851. }
  17852. if ($.inArray(iRow1, groupInfo.iRows) < 0) {
  17853. groupInfo.iRows.push(iRow1);
  17854. groupInfo.rows.push(row1);
  17855. }
  17856. }
  17857. }
  17858. }
  17859. };
  17860. if (xlen === 0 || aggrlen === 0) {
  17861. throw ("xDimension or aggregates options are not set!");
  17862. }
  17863. // ****************************************************************
  17864. // The step 1: scan input data and build the list of unique indexes
  17865. // ****************************************************************
  17866. xIndex = indexDataBy(xDimension, o.skipSortByX, o.compareVectorsByX);
  17867. yIndex = indexDataBy(yDimension, o.skipSortByY, o.compareVectorsByY);
  17868. // save to be used probably later
  17869. options.xIndex = xIndex;
  17870. options.yIndex = yIndex;
  17871. // *******************************************
  17872. // The step 2: build colModel and groupOptions
  17873. // *******************************************
  17874. // fill the first xlen columns of colModel and fill the groupOptions
  17875. // the names of the first columns will be "x"+i. The first column have the name "x0".
  17876. for (i = 0; i < xlen; i++) {
  17877. x = xDimension[i];
  17878. cm = {
  17879. name: "x" + i,
  17880. label: x.label != null ?
  17881. ($.isFunction(x.label) ? x.label.call(self, x, i, o) : x.label) :
  17882. x.dataName,
  17883. frozen: o.frozenStaticCols
  17884. };
  17885. if (i < xlen - 1 && !x.skipGrouping && !x.additionalProperty) {
  17886. // based on xDimension levels build grouping
  17887. groupingView.groupField.push(cm.name);
  17888. groupingView.groupSummary.push(o.groupSummary);
  17889. groupingView.groupSummaryPos.push(o.groupSummaryPos);
  17890. }
  17891. cm = $.extend(cm, x);
  17892. delete cm.dataName;
  17893. delete cm.footerText;
  17894. if (!x.additionalProperty) {
  17895. colModel.push(cm);
  17896. groupOptions.sortname = cm.name;
  17897. } else {
  17898. additionalProperties.push(cm.name);
  17899. }
  17900. }
  17901. if (xlen < 2) {
  17902. groupOptions.grouping = false; // no grouping is needed
  17903. }
  17904. groupingView.hideFirstGroupCol = true;
  17905. // Fill hasGroupTotal and groupColumnsPerLevel arrays
  17906. // The hasGroupTotal just shows whether one need create additional totals for every group.
  17907. for (i = 0; i < ylen; i++) {
  17908. y = yDimension[i];
  17909. hasGroupTotal.push(y.totals || y.rowTotals || y.totalText || y.totalHeader ? true : false);
  17910. }
  17911. // fill other columns of colModel based on collected uniqueYData and aggregates options
  17912. // the names of the first columns will be "y"+i in case of one aggregate and
  17913. // "y"+i+"a"+k in case of multiple aggregates. The name of the first "y"-column is "y0" or "y0a0"
  17914. // The next function build and insert item in colModel
  17915. // colType: 0 - means standard column, 1 - total group, 2 - grand total
  17916. previousY = yIndex.getItem(0);
  17917. addColumnToColModel(0, ylen - 1, 0); // add standard column
  17918. yIndexLength = yIndex.getIndexLength();
  17919. for (iYData = 1; iYData < yIndexLength; iYData++) {
  17920. itemYData = yIndex.getItem(iYData);
  17921. /*
  17922. * find where (on which level) the itemYData have the differences to
  17923. * the previous y (previousY). If the level has (totals:true/rowTotals:true) in yDimension
  17924. * then one should insert new total columns for all levels starting with the highest one
  17925. * (yDimension[yDimension.length-1]) and till the current one.
  17926. */
  17927. i = yIndex.getIndexOfDifferences(itemYData, previousY);
  17928. for (k = headerLevels - 1; k >= i; k--) {
  17929. if (hasGroupTotal[k]) {
  17930. addColumnToColModel(1, k, iYData - 1); // add group total columns
  17931. }
  17932. }
  17933. previousY = itemYData;
  17934. addColumnToColModel(0, ylen - 1, iYData); // add standard column
  17935. }
  17936. // finalize of all totals
  17937. for (i = headerLevels - 1; i >= 0; i--) {
  17938. if (hasGroupTotal[i]) {
  17939. addColumnToColModel(1, i, yIndexLength - 1); // add the last group total columns
  17940. }
  17941. }
  17942. // add total columns calculated over all data of the row
  17943. if (isRowTotal) {
  17944. addColumnToColModel(2);
  17945. }
  17946. // ********************************
  17947. // The step 3: build column headers
  17948. // ********************************
  17949. // initialize colHeaders
  17950. previousY = yIndex.getItem(0);
  17951. for (k = 0; k < headerLevels; k++) {
  17952. colHeaders.push({
  17953. useColSpanStyle: o.useColSpanStyle,
  17954. groupHeaders: [{
  17955. titleText: ($.isFunction(yDimension[k].label) ?
  17956. yDimension[k].label.call(self, { yData: previousY[k], yIndex: previousY, yLevel: k, pivotOptions: o }) :
  17957. previousY[k]),
  17958. startColumnName: aggrlen === 1 ? "y0" : "y0a0",
  17959. numberOfColumns: aggrlen
  17960. }]
  17961. });
  17962. }
  17963. for (iYData = 1; iYData < yIndexLength; iYData++) {
  17964. itemYData = yIndex.getItem(iYData);
  17965. i = yIndex.getIndexOfDifferences(itemYData, previousY);
  17966. // We placed QNIQUE data in uniqueYData array.
  17967. // So we always find a difference on one level
  17968. addGroupTotalHeaders(iYData, i, previousY);
  17969. // add column headers which corresponds the main data
  17970. for (k = headerLevels - 1; k >= i; k--) {
  17971. colHeaders[k].groupHeaders.push({
  17972. titleText: ($.isFunction(yDimension[k].label) ?
  17973. yDimension[k].label.call(self, { yData: itemYData[k], yIndex: itemYData, yLevel: k, pivotOptions: o }) :
  17974. itemYData[k]),
  17975. startColumnName: "y" + iYData + (aggrlen === 1 ? "" : "a0"),
  17976. numberOfColumns: aggrlen
  17977. });
  17978. }
  17979. for (k = 0; k < i; k++) {
  17980. groupHeaders = colHeaders[k].groupHeaders;
  17981. groupHeaders[groupHeaders.length - 1].numberOfColumns += aggrlen;
  17982. }
  17983. previousY = itemYData;
  17984. }
  17985. addGroupTotalHeaders(yIndexLength, 0, previousY);
  17986. // fill groupHeaders without taking in consideration group total columns
  17987. if (isRowTotal) {
  17988. for (i = 0; i < headerLevels; i++) {
  17989. colHeaders[i].groupHeaders.push({
  17990. titleText: (i < headerLevels - 1 ? "" : o.totalHeader || ""),
  17991. startColumnName: "t" + (aggrlen === 1 ? "" : "a0"),
  17992. numberOfColumns: aggrlen
  17993. });
  17994. }
  17995. }
  17996. // *****************************
  17997. // The step 4: fill data of grid
  17998. // *****************************
  17999. xIndexLength = xIndex.getIndexLength();
  18000. for (iXData = 0; iXData < xIndexLength; iXData++) {
  18001. itemXData = xIndex.getItem(iXData);
  18002. pivotInfos = { iX: iXData, x: itemXData };
  18003. outputItem = { pivotInfos: pivotInfos }; // item of output data
  18004. // itemXData corresponds to the row of output data
  18005. for (i = 0; i < xlen; i++) {
  18006. // fill first columns of data
  18007. outputItem["x" + i] = itemXData[i];
  18008. }
  18009. indexesOfDataWithTheSameXValues = xIndex.getIndexesOfSourceData(iXData);
  18010. // The rows of input data with indexes from indexesOfDataWithTheSameXValues contains itemXData
  18011. // Now we build columns of itemXData row
  18012. if (isRowTotal) {
  18013. for (k = 0; k < aggrlen; k++) {
  18014. aggrContextTotalRows[k] = createTotalAggregation(k);
  18015. }
  18016. }
  18017. previousY = null;
  18018. initializeGroupTotals();
  18019. for (iYData = 0; iYData < yIndexLength; iYData++) {
  18020. itemYData = yIndex.getItem(iYData);
  18021. indexesOfDataWithTheSameYValues = yIndex.getIndexesOfSourceData(iYData);
  18022. // we calculate aggregate in every itemYData
  18023. for (k = 0; k < aggrlen; k++) {
  18024. if (previousY !== null) { // empty input data
  18025. finalizeGroupTotals(iYData - 1, itemYData, previousY, k);
  18026. }
  18027. iRows = [];
  18028. for (i = 0; i < indexesOfDataWithTheSameYValues.length; i++) {
  18029. iRowsY = indexesOfDataWithTheSameYValues[i];
  18030. if ($.inArray(iRowsY, indexesOfDataWithTheSameXValues) >= 0) {
  18031. iRows.push(iRowsY);
  18032. }
  18033. }
  18034. if (iRows.length > 0) {
  18035. // iRows array have all indexes of input data which have both itemXData and itemYData
  18036. // We need calculate aggregate agr over all the items
  18037. rows = new Array(iRows.length);
  18038. agr = aggregates[k];
  18039. aggrContext = new Aggregation(agr.aggregator, self, options);
  18040. for (iRow = 0; iRow < iRows.length; iRow++) {
  18041. i = iRows[iRow];
  18042. row = data[i];
  18043. rows[iRow] = row;
  18044. aggrContext.calc(row[agr.member], agr.member, row, i, data);
  18045. if (isRowTotal) {
  18046. aggrTotal = aggrContextTotalRows[k];
  18047. aggrTotal.calc(row[agr.member], agr.member, row, i, data);
  18048. gi = aggrTotal.groupInfo;
  18049. if ($.inArray(i, gi.iYs) < 0) {
  18050. gi.iYs.push(iYData);
  18051. gi.ys.push(itemYData);
  18052. }
  18053. if ($.inArray(i, gi.iRows) < 0) {
  18054. gi.iRows.push(i);
  18055. gi.rows.push(row);
  18056. }
  18057. }
  18058. calculateGroupTotals(itemYData, previousY, agr, k, row, i, iYData);
  18059. }
  18060. cmName = "y" + iYData + (aggrlen === 1 ? "" : "a" + k);
  18061. aggrContext.getResult(outputItem, cmName);
  18062. pivotInfos[cmName] = {
  18063. colType: 0, // standard row
  18064. iY: iYData,
  18065. y: itemYData,
  18066. iA: k,
  18067. a: agr,
  18068. iRows: iRows,
  18069. rows: rows
  18070. };
  18071. }
  18072. }
  18073. previousY = itemYData;
  18074. }
  18075. if (previousY !== null) { // if non-empty input data
  18076. for (k = 0; k < aggrlen; k++) {
  18077. finalizeGroupTotals(yIndexLength - 1, previousY, previousY, k);
  18078. }
  18079. }
  18080. if (isRowTotal) {
  18081. for (k = 0; k < aggrlen; k++) {
  18082. cmName = "t" + (aggrlen === 1 ? "" : "a" + k);
  18083. aggrTotal = aggrContextTotalRows[k];
  18084. aggrTotal.getResult(outputItem, cmName);
  18085. gi = aggrTotal.groupInfo;
  18086. pivotInfos[cmName] = {
  18087. colType: 2, // row total
  18088. iA: k,
  18089. a: aggregates[k],
  18090. iRows: gi.iRows,
  18091. rows: gi.rows,
  18092. iYs: gi.iYs,
  18093. ys: gi.ys
  18094. };
  18095. }
  18096. }
  18097. outputItems.push(outputItem);
  18098. }
  18099. // *****************************
  18100. // The step 5: fill total footer
  18101. // *****************************
  18102. if (o.footerTotals || o.colTotals) {
  18103. nRows = outputItems.length;
  18104. for (i = 0; i < xlen; i++) {
  18105. summaries["x" + i] = xDimension[i].footerText || "";
  18106. }
  18107. for (i = xlen; i < colModel.length; i++) {
  18108. cmName = colModel[i].name;
  18109. aggrContext = new Aggregation(o.footerAggregator || "sum", self, options);
  18110. for (iRow = 0; iRow < nRows; iRow++) {
  18111. outputItem = outputItems[iRow];
  18112. aggrContext.calc(outputItem[cmName], cmName, outputItem, iRow, outputItems);
  18113. }
  18114. aggrContext.getResult(summaries, cmName);
  18115. }
  18116. }
  18117. // return the final result.
  18118. options.colHeaders = colHeaders;
  18119. return {
  18120. colModel: colModel,
  18121. additionalProperties: additionalProperties,
  18122. options: options,
  18123. rows: outputItems,
  18124. groupOptions: groupOptions,
  18125. groupHeaders: colHeaders,
  18126. summary: summaries
  18127. };
  18128. },
  18129. jqPivot: function (data, pivotOpt, gridOpt, ajaxOpt) {
  18130. return this.each(function () {
  18131. var $t = this, $self = $($t), $j = $.fn.jqGrid;
  18132. function pivot() {
  18133. var pivotGrid = $j.pivotSetup.call($self, data, pivotOpt),
  18134. gHead = pivotGrid.groupHeaders,
  18135. assocArraySize = function (obj) {
  18136. // http://stackoverflow.com/a/6700/11236
  18137. var size = 0, key;
  18138. for (key in obj) {
  18139. if (obj.hasOwnProperty(key)) {
  18140. size++;
  18141. }
  18142. }
  18143. return size;
  18144. },
  18145. footerrow = assocArraySize(pivotGrid.summary) > 0 ? true : false,
  18146. groupingView = pivotGrid.groupOptions.groupingView,
  18147. query = jgrid.from.call($t, pivotGrid.rows), i;
  18148. if (!pivotOpt.skipSortByX) {
  18149. for (i = 0; i < groupingView.groupField.length; i++) {
  18150. query.orderBy(groupingView.groupField[i],
  18151. gridOpt != null && gridOpt.groupingView && gridOpt.groupingView.groupOrder != null && gridOpt.groupingView.groupOrder[i] === "desc" ? "d" : "a",
  18152. "text",
  18153. "");
  18154. }
  18155. }
  18156. pivotOpt.data = data;
  18157. $j.call($self, $.extend(true, {
  18158. datastr: $.extend(query.select(), footerrow ? { userdata: pivotGrid.summary } : {}),
  18159. datatype: "jsonstring",
  18160. footerrow: footerrow,
  18161. userDataOnFooter: footerrow,
  18162. colModel: pivotGrid.colModel,
  18163. additionalProperties: pivotGrid.additionalProperties,
  18164. pivotOptions: pivotGrid.options,
  18165. viewrecords: true,
  18166. sortname: pivotOpt.xDimension[0].dataName // ?????
  18167. }, pivotGrid.groupOptions, gridOpt || {}));
  18168. if (gHead.length) {
  18169. for (i = 0; i < gHead.length; i++) {
  18170. // Multiple calls of setGroupHeaders for one grid are wrong,
  18171. // but there are produces good results in case of usage
  18172. // useColSpanStyle: false option. The rowspan values
  18173. // needed be increased in case of usage useColSpanStyle: true
  18174. if (gHead[i] && gHead[i].groupHeaders.length) {
  18175. $j.setGroupHeaders.call($self, gHead[i]);
  18176. }
  18177. }
  18178. }
  18179. if (pivotOpt.frozenStaticCols) {
  18180. $j.setFrozenColumns.call($self);
  18181. }
  18182. }
  18183. if (typeof data === "string") {
  18184. $.ajax($.extend({
  18185. url: data,
  18186. dataType: "json",
  18187. success: function (data1) {
  18188. data = jgrid.getAccessor(data1, ajaxOpt && ajaxOpt.reader ? ajaxOpt.reader : "rows");
  18189. pivot();
  18190. }
  18191. }, ajaxOpt || {}));
  18192. } else {
  18193. pivot();
  18194. }
  18195. });
  18196. }
  18197. });
  18198. // end module grid.pivot
  18199. /**
  18200. * jqGrid extension for SubGrid Data
  18201. * Copyright (c) 2008-2014, Tony Tomov, tony@trirand.com
  18202. * Copyright (c) 2014-2018, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  18203. * Dual licensed under the MIT and GPL licenses:
  18204. * http://www.opensource.org/licenses/mit-license.php
  18205. * http://www.gnu.org/licenses/gpl-2.0.html
  18206. **/
  18207. // begin module grid.subgrid
  18208. var subGridFeedback = function () {
  18209. var args = $.makeArray(arguments);
  18210. args[0] = "subGrid" + args[0].charAt(0).toUpperCase() + args[0].substring(1);
  18211. args.unshift("");
  18212. args.unshift("");
  18213. args.unshift(this.p);
  18214. return jgrid.feedback.apply(this, args);
  18215. },
  18216. collapseOrExpand = function (rowid, className) {
  18217. return this.each(function () {
  18218. if (this.grid && rowid != null && this.p.subGrid === true) {
  18219. var tr = $(this).jqGrid("getInd", rowid, true);
  18220. $(tr).find(">td." + className).trigger("click");
  18221. }
  18222. });
  18223. };
  18224. jgrid.extend({
  18225. setSubGrid: function () {
  18226. return this.each(function () {
  18227. var p = this.p, $self = $(this), cm = p.subGridModel[0], i,
  18228. getIcon = function (path) {
  18229. return $self.jqGrid("getIconRes", path);
  18230. };
  18231. p.subGridOptions = $.extend({
  18232. commonIconClass: getIcon("subgrid.common"),
  18233. plusicon: getIcon("subgrid.plus"),
  18234. minusicon: getIcon("subgrid.minus"),
  18235. openicon: (p.direction === "rtl" ? getIcon("subgrid.openRtl") : getIcon("subgrid.openLtr")),
  18236. expandOnLoad: false,
  18237. delayOnLoad: 50,
  18238. selectOnExpand: false,
  18239. selectOnCollapse: false,
  18240. reloadOnExpand: true
  18241. }, p.subGridOptions || {});
  18242. p.colNames.unshift("");
  18243. p.colModel.unshift({
  18244. name: "subgrid",
  18245. width: jgrid.cell_width ? p.subGridWidth + p.cellLayout : p.subGridWidth,
  18246. labelClasses: "jqgh_subgrid",
  18247. sortable: false,
  18248. resizable: false,
  18249. hidedlg: true,
  18250. search: false,
  18251. fixed: true,
  18252. frozen: true
  18253. });
  18254. if (cm) {
  18255. cm.align = $.extend([], cm.align || []);
  18256. for (i = 0; i < cm.name.length; i++) {
  18257. cm.align[i] = cm.align[i] || "left";
  18258. }
  18259. }
  18260. });
  18261. },
  18262. addSubGridCell: function (pos, iRow, rowid, item) {
  18263. var self = this[0], subGridOptions = self.p.subGridOptions,
  18264. hasSubgrid = $.isFunction(subGridOptions.hasSubgrid) ?
  18265. subGridOptions.hasSubgrid.call(self, { rowid: rowid, iRow: iRow, iCol: pos, data: item }) :
  18266. true;
  18267. return self.p == null ? "" :
  18268. "<td role='gridcell' class='" + base.getGuiStyles.call(this, "subgrid.tdStart", hasSubgrid ? "ui-sgcollapsed sgcollapsed" : "") + "' " +
  18269. self.formatCol(pos, iRow) + ">" +
  18270. (hasSubgrid ? "<div class='" + base.getGuiStyles.call(this, "subgrid.buttonDiv", "sgbutton-div") +
  18271. "'><a role='button' class='" + base.getGuiStyles.call(this, "subgrid.button", "sgbutton") +
  18272. "'><span class='" + jgrid.mergeCssClasses(subGridOptions.commonIconClass, subGridOptions.plusicon) + "'></span></a></div>" : "&nbsp;") +
  18273. "</td>";
  18274. },
  18275. addSubGrid: function (pos, sind) {
  18276. return this.each(function () {
  18277. var ts = this, p = ts.p, cm = p.subGridModel[0],
  18278. getSubgridStyle = function (name, calsses) {
  18279. return base.getGuiStyles.call(ts, "subgrid." + name, calsses || "");
  18280. },
  18281. thSubgridClasses = getSubgridStyle("thSubgrid", "ui-th-subgrid ui-th-column ui-th-" + p.direction),
  18282. rowSubTableClasses = getSubgridStyle("rowSubTable", "ui-subtblcell"),
  18283. rowClasses = getSubgridStyle("row", "ui-subgrid ui-row-" + p.direction),
  18284. tdWithIconClasses = getSubgridStyle("tdWithIcon", "subgrid-cell"),
  18285. tdDataClasses = getSubgridStyle("tdData", "subgrid-data"),
  18286. subGridCell = function ($tr, cell, pos1) {
  18287. var align = cm.align[pos1],
  18288. $td = $("<td" +
  18289. (align ? " style='text-align:" + align + ";'" : "") +
  18290. "></td>").html(cell);
  18291. $tr.append($td);
  18292. },
  18293. fillXmlBody = function (data, $tbody) {
  18294. var sgmap = p.xmlReader.subgrid;
  18295. $(sgmap.root + " " + sgmap.row, data).each(function () {
  18296. var f, i, $tr = $("<tr class='" + rowSubTableClasses + "'></tr>");
  18297. if (sgmap.repeatitems === true) {
  18298. $(sgmap.cell, this).each(function (j) {
  18299. subGridCell($tr, $(this).text() || "&#160;", j);
  18300. });
  18301. } else {
  18302. f = cm.mapping || cm.name;
  18303. if (f) {
  18304. for (i = 0; i < f.length; i++) {
  18305. subGridCell($tr, jgrid.getXmlData(this, f[i]) || "&#160;", i);
  18306. }
  18307. }
  18308. }
  18309. $tbody.append($tr);
  18310. });
  18311. },
  18312. fillJsonBody = function (data, $tbody) {
  18313. var $tr, i, j, f, cur, sgmap = p.jsonReader.subgrid,
  18314. result = jgrid.getAccessor(data, sgmap.root);
  18315. if (result != null) {
  18316. for (i = 0; i < result.length; i++) {
  18317. cur = result[i];
  18318. $tr = $("<tr class='" + rowSubTableClasses + "'></tr>");
  18319. if (sgmap.repeatitems === true) {
  18320. if (sgmap.cell) {
  18321. cur = cur[sgmap.cell];
  18322. }
  18323. for (j = 0; j < cur.length; j++) {
  18324. subGridCell($tr, cur[j] || "&#160;", j);
  18325. }
  18326. } else {
  18327. f = cm.mapping || cm.name;
  18328. if (f.length) {
  18329. for (j = 0; j < f.length; j++) {
  18330. subGridCell($tr, jgrid.getAccessor(cur, f[j]) || "&#160;", j);
  18331. }
  18332. }
  18333. }
  18334. $tbody.append($tr);
  18335. }
  18336. }
  18337. },
  18338. subGridXmlOrJson = function (sjxml, sbid, fullBody) {
  18339. var $th, i, subgridTableClasses = getSubgridStyle("legacyTable", "ui-jqgrid-legacy-subgrid" +
  18340. (p.altRows === true && $(ts).jqGrid("isBootstrapGuiStyle") ? " table-striped" : "")),
  18341. $table = $("<table" +
  18342. (subgridTableClasses ? " style='width:1px' role='presentation' class='" + subgridTableClasses + "'" : "") +
  18343. "><thead></thead><tbody></tbody></table>"),
  18344. $tr = $("<tr></tr>");
  18345. ts.grid.endReq.call(ts);
  18346. for (i = 0; i < cm.name.length; i++) {
  18347. $th = $("<th class='" + thSubgridClasses + "'></th>")
  18348. .html(cm.name[i])
  18349. .width(cm.width[i]);
  18350. $tr.append($th);
  18351. }
  18352. $tr.appendTo($table[0].tHead);
  18353. fullBody(sjxml, $($table[0].tBodies[0]));
  18354. $("#" + jqID(p.id + "_" + sbid)).append($table);
  18355. return false;
  18356. },
  18357. populatesubgrid = function (rd) {
  18358. var sid = $(rd).attr("id"), dp = { nd_: (new Date().getTime()) }, iCol, j;
  18359. dp[p.prmNames.subgridid] = sid;
  18360. if (!cm) {
  18361. return false;
  18362. }
  18363. if (cm.params) {
  18364. for (j = 0; j < cm.params.length; j++) {
  18365. iCol = p.iColByName[cm.params[j]];
  18366. if (iCol !== undefined) {
  18367. dp[p.colModel[iCol].name] = $(rd.cells[iCol]).text().replace(/\&#160\;/ig, "");
  18368. }
  18369. }
  18370. }
  18371. if (!ts.grid.hDiv.loading) {
  18372. ts.grid.beginReq.call(ts);
  18373. if (!p.subgridtype) {
  18374. p.subgridtype = p.datatype;
  18375. }
  18376. if ($.isFunction(p.subgridtype)) {
  18377. p.subgridtype.call(ts, dp);
  18378. } else {
  18379. p.subgridtype = p.subgridtype.toLowerCase();
  18380. }
  18381. switch (p.subgridtype) {
  18382. case "xml":
  18383. case "json":
  18384. $.ajax($.extend({
  18385. type: p.mtype,
  18386. url: $.isFunction(p.subGridUrl) ? p.subGridUrl.call(ts, dp) : p.subGridUrl,
  18387. dataType: p.subgridtype,
  18388. context: sid,
  18389. data: jgrid.serializeFeedback.call(ts, p.serializeSubGridData, "jqGridSerializeSubGridData", dp),
  18390. success: function (data) {
  18391. subGridXmlOrJson(
  18392. data,
  18393. this,
  18394. p.subgridtype === "xml" ? fillXmlBody : fillJsonBody
  18395. );
  18396. },
  18397. error: function (jqXHR, textStatus, errorThrown) {
  18398. var loadError = p.loadSubgridError === undefined ?
  18399. p.loadError :
  18400. p.loadSubgridError;
  18401. ts.grid.endReq.call(ts);
  18402. if ($.isFunction(loadError)) {
  18403. loadError.call(ts, jqXHR, textStatus, errorThrown);
  18404. }
  18405. // for compatibility only
  18406. if (!p.subGridOptions.noEmptySubgridOnError) {
  18407. subGridXmlOrJson(
  18408. null,
  18409. this,
  18410. p.subgridtype === "xml" ? fillXmlBody : fillJsonBody
  18411. );
  18412. }
  18413. }
  18414. }, jgrid.ajaxOptions, p.ajaxSubgridOptions || {}));
  18415. break;
  18416. }
  18417. }
  18418. return false;
  18419. },
  18420. onClick = function () {
  18421. var tr = $(this).parent("tr")[0], r = tr.nextSibling, rowid = tr.id, subgridDivId = p.id + "_" + rowid, atd,
  18422. iconClass = function (iconName) {
  18423. return jgrid.mergeCssClasses(p.subGridOptions.commonIconClass, p.subGridOptions[iconName]);
  18424. },
  18425. nhc = 1;
  18426. $.each(p.colModel, function () {
  18427. if (this.hidden === true || this.name === "rn" || this.name === "cb") {
  18428. // ??? probably one should don't calculate hidden columns of subgrid?
  18429. // (remove this.hidden === true part from the if) ???
  18430. nhc++;
  18431. }
  18432. });
  18433. if ($(this).hasClass("sgcollapsed")) {
  18434. if (p.subGridOptions.reloadOnExpand === true || (p.subGridOptions.reloadOnExpand === false && !$(r).hasClass("ui-subgrid"))) {
  18435. atd = pos >= 1 ? "<td colspan='" + pos + "'>&#160;</td>" : "";
  18436. if (!subGridFeedback.call(ts, "beforeExpand", subgridDivId, rowid)) {
  18437. return;
  18438. }
  18439. $(tr).after("<tr role='row' class='" + rowClasses + "'>" + atd + "<td class='" + tdWithIconClasses +
  18440. "'><span class='" + iconClass("openicon") + "'></span></td><td colspan='" + parseInt(p.colNames.length - nhc, 10) +
  18441. "' class='" + tdDataClasses + "'><div id='" + subgridDivId + "' class='tablediv'></div></td></tr>");
  18442. $(ts).triggerHandler("jqGridSubGridRowExpanded", [subgridDivId, rowid]);
  18443. if ($.isFunction(p.subGridRowExpanded)) {
  18444. p.subGridRowExpanded.call(ts, subgridDivId, rowid);
  18445. } else {
  18446. populatesubgrid(tr);
  18447. }
  18448. } else {
  18449. $(r).show();
  18450. }
  18451. $(this).html(
  18452. "<div class='" + base.getGuiStyles.call(ts, "subgrid.buttonDiv", "sgbutton-div") +
  18453. "'><a role='button' class='" + base.getGuiStyles.call(ts, "subgrid.button", "sgbutton") +
  18454. "'><span class='" + iconClass("minusicon") + "'></span></a></div>"
  18455. ).removeClass("sgcollapsed").addClass("sgexpanded");
  18456. if (p.subGridOptions.selectOnExpand) {
  18457. $(ts).jqGrid("setSelection", rowid);
  18458. }
  18459. } else if ($(this).hasClass("sgexpanded")) {
  18460. if (!subGridFeedback.call(ts, "beforeCollapse", subgridDivId, rowid)) {
  18461. return;
  18462. }
  18463. if (p.subGridOptions.reloadOnExpand === true) {
  18464. $(r).remove(".ui-subgrid");
  18465. } else if ($(r).hasClass("ui-subgrid")) { // incase of dynamic deleting
  18466. $(r).hide();
  18467. }
  18468. $(this).html(
  18469. "<div class='" + base.getGuiStyles.call(ts, "subgrid.buttonDiv", "sgbutton-div") +
  18470. "'><a role='button' class='" + base.getGuiStyles.call(ts, "subgrid.button", "sgbutton") +
  18471. "'><span class='" + iconClass("plusicon") + "'></span></a></div>"
  18472. ).removeClass("sgexpanded").addClass("sgcollapsed");
  18473. if (p.subGridOptions.selectOnCollapse) {
  18474. $(ts).jqGrid("setSelection", rowid);
  18475. }
  18476. }
  18477. return false;
  18478. },
  18479. len,
  18480. tr1,
  18481. $td1,
  18482. iRow = 1;
  18483. if (!ts.grid) {
  18484. return;
  18485. }
  18486. len = ts.rows.length;
  18487. if (sind !== undefined && sind > 0) {
  18488. iRow = sind;
  18489. len = sind + 1;
  18490. }
  18491. while (iRow < len) {
  18492. tr1 = ts.rows[iRow];
  18493. if ($(tr1).hasClass("jqgrow")) {
  18494. $td1 = $(tr1.cells[pos]);
  18495. if ($td1.hasClass("ui-sgcollapsed")) {
  18496. if (p.scroll) {
  18497. $td1.off("click");
  18498. }
  18499. $td1.on("click", onClick);
  18500. }
  18501. }
  18502. iRow++;
  18503. }
  18504. if (p.subGridOptions.expandOnLoad === true) {
  18505. var iColSubgrid = p.iColByName.subgrid;
  18506. $(ts.rows).filter(".jqgrow").each(function (index, row) {
  18507. $(row.cells[iColSubgrid])
  18508. .filter(".sgcollapsed")
  18509. .children(".sgbutton-div")
  18510. .children(".sgbutton")
  18511. .click();
  18512. });
  18513. }
  18514. ts.subGridXml = function (xml, sid) {
  18515. return subGridXmlOrJson(xml, sid, fillXmlBody);
  18516. };
  18517. ts.subGridJson = function (json, sid) {
  18518. return subGridXmlOrJson(json, sid, fillJsonBody);
  18519. };
  18520. });
  18521. },
  18522. expandSubGridRow: function (rowid) {
  18523. return collapseOrExpand.call(this, rowid, "sgcollapsed");
  18524. },
  18525. collapseSubGridRow: function (rowid) {
  18526. return collapseOrExpand.call(this, rowid, "sgexpanded");
  18527. },
  18528. toggleSubGridRow: function (rowid) {
  18529. return collapseOrExpand.call(this, rowid, "ui-sgcollapsed");
  18530. }
  18531. });
  18532. // end module grid.subgrid
  18533. /**
  18534. Transform a table to a jqGrid.
  18535. Peter Romianowski <peter.romianowski@optivo.de>
  18536. If the first column of the table contains checkboxes or
  18537. radiobuttons then the jqGrid is made selectable.
  18538. */
  18539. // begin module grid.tbltogrid
  18540. window.tableToGrid = function (selector, options) {
  18541. $(selector).each(function () {
  18542. var self = this, $self = $(this), w, inputCheckbox, inputRadio, selectMultiple, selectSingle, selectable, a, id,
  18543. colModel = [], colNames = [], data = [], rowIds = [], rowChecked = [];
  18544. if (self.grid) {
  18545. return;//Adedd by Tony Tomov
  18546. }
  18547. // This is a small "hack" to make the width of the jqGrid 100%
  18548. $self.width("99%");
  18549. w = $self.width();
  18550. // Text whether we have single or multi select
  18551. inputCheckbox = $("tr td:first-child input[type=checkbox]:first", $self);
  18552. inputRadio = $("tr td:first-child input[type=radio]:first", $self);
  18553. selectMultiple = inputCheckbox.length > 0;
  18554. selectSingle = !selectMultiple && inputRadio.length > 0;
  18555. selectable = selectMultiple || selectSingle;
  18556. //var inputName = inputCheckbox.attr("name") || inputRadio.attr("name");
  18557. // Build up the columnModel and the data
  18558. $("th", $self).each(function () {
  18559. if (colModel.length === 0 && selectable) {
  18560. colModel.push({
  18561. name: "__selection__",
  18562. index: "__selection__",
  18563. width: 0,
  18564. hidden: true
  18565. });
  18566. colNames.push("__selection__");
  18567. } else {
  18568. colModel.push({
  18569. name: $(this).attr("id") || $.trim($.jgrid.stripHtml($(this).html())).split(" ").join("_"),
  18570. index: $(this).attr("id") || $.trim($.jgrid.stripHtml($(this).html())).split(" ").join("_"),
  18571. width: $(this).width() || 150
  18572. });
  18573. colNames.push($(this).html());
  18574. }
  18575. });
  18576. $("tbody > tr", $self).each(function () {
  18577. var row = {}, rowPos = 0;
  18578. $("td", $(this)).each(function () {
  18579. if (rowPos === 0 && selectable) {
  18580. var input = $("input", $(this)), rowId = input.attr("value");
  18581. rowIds.push(rowId || data.length);
  18582. if (input.is(":checked")) {
  18583. rowChecked.push(rowId);
  18584. }
  18585. row[colModel[rowPos].name] = input.attr("value");
  18586. } else {
  18587. row[colModel[rowPos].name] = $(this).html();
  18588. }
  18589. rowPos++;
  18590. });
  18591. if (rowPos > 0) {
  18592. data.push(row);
  18593. }
  18594. });
  18595. // Clear the original HTML table
  18596. $self.empty();
  18597. $self.jqGrid($.extend({
  18598. datatype: "local",
  18599. width: w,
  18600. colNames: colNames,
  18601. colModel: colModel,
  18602. multiselect: selectMultiple
  18603. //inputName: inputName,
  18604. //inputValueCol: imputName != null ? "__selection__" : null
  18605. }, options || {}));
  18606. // Add data
  18607. for (a = 0; a < data.length; a++) {
  18608. id = null;
  18609. if (rowIds.length > 0) {
  18610. id = rowIds[a];
  18611. if (id && id.replace) {
  18612. // We have to do this since the value of a checkbox
  18613. // or radio button can be anything
  18614. id = encodeURIComponent(id).replace(/[.\-%]/g, "_");
  18615. }
  18616. }
  18617. if (id === null) {
  18618. id = $.jgrid.randId();
  18619. }
  18620. $self.jqGrid("addRowData", id, data[a]);
  18621. }
  18622. // Set the selection
  18623. for (a = 0; a < rowChecked.length; a++) {
  18624. $self.jqGrid("setSelection", rowChecked[a]);
  18625. }
  18626. });
  18627. };
  18628. // end module grid.tbltogrid
  18629. /**
  18630. * jqGrid extension - Tree Grid
  18631. * Copyright (c) 2008-2014, Tony Tomov, tony@trirand.com
  18632. * Copyright (c) 2014-2018, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  18633. * Dual licensed under the MIT and GPL licenses:
  18634. * http://www.opensource.org/licenses/mit-license.php
  18635. * http://www.gnu.org/licenses/gpl-2.0.html
  18636. **/
  18637. // begin module grid.treegrid
  18638. var treeGridFeedback = function () {
  18639. var args = $.makeArray(arguments);
  18640. args[0] = "treeGrid" + args[0].charAt(0).toUpperCase() + args[0].substring(1);
  18641. args.unshift("");
  18642. args.unshift("");
  18643. args.unshift(this.p);
  18644. return jgrid.feedback.apply(this, args);
  18645. },
  18646. getNodeIcons = function (p, item) {
  18647. var icons = item[p.treeReader.icon_field],
  18648. treeIcons = p.treeIcons,
  18649. iconCollapsed = treeIcons.plus + " tree-plus",
  18650. iconExpanded = treeIcons.minus + " tree-minus";
  18651. if (icons && typeof icons === "string") {
  18652. icons = icons.split(",");
  18653. if (icons.length === 2) {
  18654. iconExpanded = icons[0];
  18655. iconCollapsed = icons[1];
  18656. }
  18657. }
  18658. return {
  18659. expanded: iconExpanded,
  18660. collapsed: iconCollapsed,
  18661. common: treeIcons.commonIconClass
  18662. };
  18663. };
  18664. jgrid.extend({
  18665. setTreeNode: function () {
  18666. // TODO: Move the code in setTreeGrid because it uses currently no parameters
  18667. // and it's don't make any actions with specific row
  18668. return this.each(function () {
  18669. var $t = this, $self = $($t), p = $t.p;
  18670. if (!$t.grid || !p.treeGrid) { return; }
  18671. var expanded = p.treeReader.expanded_field,
  18672. isLeaf = p.treeReader.leaf_field,
  18673. beforeSelectRow = function (e, rowid, eOrg) {
  18674. if (eOrg != null) {
  18675. var $target = $(eOrg.target),
  18676. $td = $target.closest("tr.jqgrow>td"),
  18677. $tr = $td.parent(),
  18678. expendOrCollaps = function () {
  18679. var item = p.data[p._index[stripPref(p.idPrefix, rowid)]],
  18680. collapseOrExpand = item[expanded] ? "collapse" : "expand";
  18681. if (!item[isLeaf]) {
  18682. base[collapseOrExpand + "Row"].call($self, item, $tr);
  18683. base[collapseOrExpand + "Node"].call($self, item, $tr);
  18684. }
  18685. };
  18686. if ($target.is("div.treeclick")) {
  18687. expendOrCollaps();
  18688. } else if (p.ExpandColClick) {
  18689. if ($td.length > 0 && $target.closest("span.cell-wrapper", $td).length > 0) {
  18690. expendOrCollaps();
  18691. }
  18692. }
  18693. return true; // allow selection
  18694. }
  18695. };
  18696. $self.off("jqGridBeforeSelectRow.setTreeNode");
  18697. $self.on("jqGridBeforeSelectRow.setTreeNode", beforeSelectRow);
  18698. });
  18699. },
  18700. setTreeGrid: function () {
  18701. return this.each(function () {
  18702. var $t = this, p = $t.p, nm, key, tkey, dupcols = [],
  18703. boolProp = ["leaf_field", "expanded_field", "loaded"];
  18704. if (!p.treeGrid) { return; }
  18705. if (!p.treedatatype) { $.extend($t.p, { treedatatype: p.datatype }); }
  18706. p.subGrid = false;
  18707. p.altRows = false;
  18708. p.pgbuttons = false;
  18709. p.pginput = false;
  18710. p.gridview = true;
  18711. if (p.rowTotal === null) { p.rowNum = p.maxRowNum; }
  18712. p.rowList = [];
  18713. //pico = "ui-icon-triangle-1-" + (p.direction==="rtl" ? "w" : "e");
  18714. //p.treeIcons = $.extend({plus:pico,minus:"ui-icon-triangle-1-s",leaf:"ui-icon-radio-off"},p.treeIcons || {});
  18715. p.treeIcons.plus = p.direction === "rtl" ? p.treeIcons.plusRtl : p.treeIcons.plusLtr;
  18716. if (p.treeGridModel === "nested") {
  18717. p.treeReader = $.extend({
  18718. level_field: "level",
  18719. left_field: "lft",
  18720. right_field: "rgt",
  18721. leaf_field: "isLeaf",
  18722. expanded_field: "expanded",
  18723. loaded: "loaded",
  18724. icon_field: "icon"
  18725. }, p.treeReader);
  18726. } else if (p.treeGridModel === "adjacency") {
  18727. p.treeReader = $.extend({
  18728. level_field: "level",
  18729. parent_id_field: "parent",
  18730. leaf_field: "isLeaf",
  18731. expanded_field: "expanded",
  18732. loaded: "loaded",
  18733. icon_field: "icon"
  18734. }, p.treeReader);
  18735. }
  18736. for (key in p.colModel) {
  18737. if (p.colModel.hasOwnProperty(key)) {
  18738. nm = p.colModel[key].name;
  18739. for (tkey in p.treeReader) {
  18740. if (p.treeReader.hasOwnProperty(tkey) && p.treeReader[tkey] === nm) {
  18741. dupcols.push(nm);
  18742. }
  18743. }
  18744. }
  18745. }
  18746. $.each(p.treeReader, function (prop) {
  18747. var name = String(this);
  18748. if (name && $.inArray(name, dupcols) === -1) {
  18749. if ($.inArray(prop, boolProp) >= 0) {
  18750. p.additionalProperties.push({
  18751. name: name,
  18752. search: false,
  18753. convert: function (data) {
  18754. return data === true || String(data).toLowerCase() === "true" || String(data) === "1" ? true : data;
  18755. }
  18756. });
  18757. } else {
  18758. p.additionalProperties.push(name);
  18759. }
  18760. }
  18761. });
  18762. });
  18763. },
  18764. expandRow: function (record) {
  18765. this.each(function () {
  18766. var $t = this, $self = $($t), p = $t.p;
  18767. if (!$t.grid || !p.treeGrid) { return; }
  18768. var expanded = p.treeReader.expanded_field, rowid = record[p.localReader.id]; // without prefix
  18769. if (!treeGridFeedback.call($t, "beforeExpandRow", { rowid: rowid, item: record })) { return; }
  18770. var childern = base.getNodeChildren.call($self, record);
  18771. $(childern).each(function () {
  18772. var id = p.idPrefix + getAccessor(this, p.localReader.id);
  18773. $(base.getGridRowById.call($self, id)).css("display", "");
  18774. if (this[expanded]) {
  18775. base.expandRow.call($self, this);
  18776. }
  18777. });
  18778. treeGridFeedback.call($t, "afterExpandRow", { rowid: rowid, item: record });
  18779. });
  18780. },
  18781. collapseRow: function (record) {
  18782. this.each(function () {
  18783. var $t = this, $self = $($t), p = $t.p;
  18784. if (!$t.grid || !p.treeGrid) { return; }
  18785. var expanded = p.treeReader.expanded_field, rowid = record[p.localReader.id]; // without prefix
  18786. if (!treeGridFeedback.call($t, "beforeCollapseRow", { rowid: rowid, item: record })) { return; }
  18787. var childern = base.getNodeChildren.call($self, record);
  18788. $(childern).each(function () {
  18789. var id = p.idPrefix + getAccessor(this, p.localReader.id);
  18790. $(base.getGridRowById.call($self, id)).css("display", "none");
  18791. if (this[expanded]) {
  18792. base.collapseRow.call($self, this);
  18793. }
  18794. });
  18795. treeGridFeedback.call($t, "afterCollapseRow", { rowid: rowid, item: record });
  18796. });
  18797. },
  18798. // NS ,adjacency models
  18799. getRootNodes: function () {
  18800. var result = [];
  18801. this.each(function () {
  18802. var $t = this, p = $t.p;
  18803. if (!$t.grid || !p.treeGrid) { return; }
  18804. switch (p.treeGridModel) {
  18805. case "nested":
  18806. var level = p.treeReader.level_field;
  18807. $(p.data).each(function () {
  18808. if (parseInt(this[level], 10) === parseInt(p.tree_root_level, 10)) {
  18809. result.push(this);
  18810. }
  18811. });
  18812. break;
  18813. case "adjacency":
  18814. var parentId = p.treeReader.parent_id_field;
  18815. $(p.data).each(function () {
  18816. if (this[parentId] === null || String(this[parentId]).toLowerCase() === "null") {
  18817. result.push(this);
  18818. }
  18819. });
  18820. break;
  18821. }
  18822. });
  18823. return result;
  18824. },
  18825. getNodeDepth: function (rc) {
  18826. var ret = null;
  18827. this.each(function () {
  18828. var $t = this, p = $t.p;
  18829. if (!$t.grid || !p.treeGrid) { return; }
  18830. switch (p.treeGridModel) {
  18831. case "nested":
  18832. var level = p.treeReader.level_field;
  18833. ret = parseInt(rc[level], 10) - parseInt(p.tree_root_level, 10);
  18834. break;
  18835. case "adjacency":
  18836. ret = base.getNodeAncestors.call($($t), rc).length;
  18837. break;
  18838. }
  18839. });
  18840. return ret;
  18841. },
  18842. getNodeParent: function (rc) {
  18843. // var $t = this instanceof $ && this.length > 0 ? this[0] : this;
  18844. var $t = this[0];
  18845. if (!$t || !$t.grid || $t.p == null || !$t.p.treeGrid || rc == null) { return null; }
  18846. var p = $t.p, treeReader = p.treeReader, parentIdName = treeReader.parent_id_field, parentId = rc[parentIdName];
  18847. if (p.treeGridModel === "nested") {
  18848. var result = null,
  18849. lftc = treeReader.left_field,
  18850. rgtc = treeReader.right_field,
  18851. levelc = treeReader.level_field,
  18852. lft = parseInt(rc[lftc], 10), rgt = parseInt(rc[rgtc], 10), level = parseInt(rc[levelc], 10);
  18853. $(p.data).each(function () {
  18854. if (parseInt(this[levelc], 10) === level - 1 && parseInt(this[lftc], 10) < lft && parseInt(this[rgtc], 10) > rgt) {
  18855. result = this;
  18856. return false;
  18857. }
  18858. });
  18859. return result;
  18860. }
  18861. if (parentId === null || parentId === "null") { return null; }
  18862. var iParent = p._index[parentId];
  18863. return iParent !== undefined ? p.data[iParent] : null;
  18864. },
  18865. getNodeChildren: function (rc) {
  18866. var result = [];
  18867. this.each(function () {
  18868. var $t = this, p = $t.p;
  18869. if (!$t.grid || !p.treeGrid) { return; }
  18870. switch (p.treeGridModel) {
  18871. case "nested":
  18872. var lftc = p.treeReader.left_field, rgtc = p.treeReader.right_field, levelc = p.treeReader.level_field,
  18873. lft = parseInt(rc[lftc], 10),
  18874. rgt = parseInt(rc[rgtc], 10),
  18875. level = parseInt(rc[levelc], 10);
  18876. $(p.data).each(function () {
  18877. if (parseInt(this[levelc], 10) === level + 1 && parseInt(this[lftc], 10) > lft && parseInt(this[rgtc], 10) < rgt) {
  18878. result.push(this);
  18879. }
  18880. });
  18881. break;
  18882. case "adjacency":
  18883. var parentId = p.treeReader.parent_id_field, dtid = p.localReader.id;
  18884. $(p.data).each(function () {
  18885. if (String(this[parentId]) === String(rc[dtid])) {
  18886. result.push(this);
  18887. }
  18888. });
  18889. break;
  18890. }
  18891. });
  18892. return result;
  18893. },
  18894. getFullTreeNode: function (rc) {
  18895. var result = [];
  18896. this.each(function () {
  18897. var $t = this, p = $t.p, len;
  18898. if (!$t.grid || !p.treeGrid) { return; }
  18899. switch (p.treeGridModel) {
  18900. case "nested":
  18901. var lftc = p.treeReader.left_field, rgtc = p.treeReader.right_field, levelc = p.treeReader.level_field,
  18902. lft = parseInt(rc[lftc], 10),
  18903. rgt = parseInt(rc[rgtc], 10),
  18904. level = parseInt(rc[levelc], 10);
  18905. $(p.data).each(function () {
  18906. if (parseInt(this[levelc], 10) >= level && parseInt(this[lftc], 10) >= lft && parseInt(this[lftc], 10) <= rgt) {
  18907. result.push(this);
  18908. }
  18909. });
  18910. break;
  18911. case "adjacency":
  18912. if (rc) {
  18913. result.push(rc);
  18914. var parentId = p.treeReader.parent_id_field, dtid = p.localReader.id;
  18915. $(p.data).each(function () {
  18916. var i;
  18917. len = result.length;
  18918. for (i = 0; i < len; i++) {
  18919. if (String(result[i][dtid]) === String(this[parentId])) {
  18920. result.push(this);
  18921. break;
  18922. }
  18923. }
  18924. });
  18925. }
  18926. break;
  18927. }
  18928. });
  18929. return result;
  18930. },
  18931. // End NS, adjacency Model
  18932. getNodeAncestors: function (rc) {
  18933. var ancestors = [];
  18934. this.each(function () {
  18935. var $t = this, $self = $($t), getNodeParent = base.getNodeParent;
  18936. if (!$t.grid || !$t.p.treeGrid) { return; }
  18937. var parent = getNodeParent.call($self, rc);
  18938. while (parent) {
  18939. ancestors.push(parent);
  18940. parent = getNodeParent.call($self, parent);
  18941. }
  18942. });
  18943. return ancestors;
  18944. },
  18945. isVisibleNode: function (rc) {
  18946. var result = true;
  18947. this.each(function () {
  18948. var $t = this, p = $t.p;
  18949. if (!$t.grid || !p.treeGrid) { return; }
  18950. var ancestors = base.getNodeAncestors.call($($t), rc), expanded = p.treeReader.expanded_field;
  18951. $(ancestors).each(function () {
  18952. result = result && this[expanded];
  18953. if (!result) { return false; }
  18954. });
  18955. });
  18956. return result;
  18957. },
  18958. isNodeLoaded: function (rc) {
  18959. var result;
  18960. this.each(function () {
  18961. var $t = this, p = $t.p;
  18962. if (!$t.grid || !p.treeGrid) { return; }
  18963. var isLeaf = p.treeReader.leaf_field, loaded = p.treeReader.loaded;
  18964. if (rc !== undefined) {
  18965. if (rc[loaded] !== undefined) {
  18966. result = rc[loaded];
  18967. } else if (rc[isLeaf] || base.getNodeChildren.call($($t), rc).length > 0) {
  18968. result = true;
  18969. } else {
  18970. result = false;
  18971. }
  18972. } else {
  18973. result = false;
  18974. }
  18975. });
  18976. return result;
  18977. },
  18978. expandNode: function (rc) {
  18979. return this.each(function () {
  18980. var $t = this, p = $t.p, id, rc1, icons;
  18981. if (!$t.grid || !p.treeGrid) { return; }
  18982. var treeReader = p.treeReader;
  18983. if (!rc[treeReader.expanded_field]) {
  18984. id = getAccessor(rc, p.localReader.id);
  18985. if (!treeGridFeedback.call($t, "beforeExpandNode", { rowid: id, item: rc })) { return; }
  18986. rc1 = $("#" + p.idPrefix + jqID(id), $t.grid.bDiv)[0];
  18987. rc[treeReader.expanded_field] = true;
  18988. icons = getNodeIcons(p, rc);
  18989. $("div.treeclick", rc1).removeClass(icons.collapsed).addClass(icons.common).addClass(icons.expanded);
  18990. if (p.treedatatype !== "local" && !base.isNodeLoaded.call($($t), p.data[p._index[id]]) && !$t.grid.hDiv.loading) {
  18991. // set the value which will be used during processing of the server response
  18992. // in readInput
  18993. p.treeANode = rc1.rowIndex;
  18994. p.datatype = p.treedatatype;
  18995. base.setGridParam.call($($t), {
  18996. postData: p.treeGridModel === "nested" ?
  18997. {
  18998. nodeid: id,
  18999. n_level: rc[treeReader.level_field],
  19000. n_left: rc[treeReader.left_field],
  19001. n_right: rc[treeReader.right_field]
  19002. } :
  19003. {
  19004. nodeid: id,
  19005. n_level: rc[treeReader.level_field],
  19006. parentid: rc[treeReader.parent_id_field]
  19007. }
  19008. });
  19009. $($t).trigger("reloadGrid");
  19010. rc[treeReader.loaded] = true;
  19011. base.setGridParam.call($($t), {
  19012. postData: p.treeGridModel === "nested" ?
  19013. {
  19014. nodeid: "",
  19015. n_level: "",
  19016. n_left: "",
  19017. n_right: ""
  19018. } :
  19019. {
  19020. nodeid: "",
  19021. n_level: "",
  19022. parentid: ""
  19023. }
  19024. });
  19025. }
  19026. treeGridFeedback.call($t, "afterExpandNode", { rowid: id, item: rc });
  19027. }
  19028. });
  19029. },
  19030. collapseNode: function (rc) {
  19031. return this.each(function () {
  19032. var $t = this, p = $t.p, icons;
  19033. if (!$t.grid || !p.treeGrid) { return; }
  19034. var expanded = p.treeReader.expanded_field;
  19035. if (rc[expanded]) {
  19036. var id = getAccessor(rc, p.localReader.id);
  19037. if (!treeGridFeedback.call($t, "beforeCollapseNode", { rowid: id, item: rc })) { return; }
  19038. rc[expanded] = false;
  19039. icons = getNodeIcons(p, rc);
  19040. $("#" + p.idPrefix + jqID(id), $t.grid.bDiv) // $tr
  19041. .find("div.treeclick")
  19042. .removeClass(icons.expanded)
  19043. .addClass(icons.common)
  19044. .addClass(icons.collapsed);
  19045. if (p.unloadNodeOnCollapse === true || ($.isFunction(p.unloadNodeOnCollapse) && p.unloadNodeOnCollapse.call($t, rc))) {
  19046. rc[p.treeReader.loaded] = false;
  19047. $($t).jqGrid("delTreeNode", id, true);
  19048. }
  19049. treeGridFeedback.call($t, "afterCollapseNode", { rowid: id, item: rc });
  19050. }
  19051. });
  19052. },
  19053. SortTree: function (sortname, newDir, st, datefmt) {
  19054. return this.each(function () {
  19055. var $t = this, p = $t.p, $self = $($t);
  19056. if (!$t.grid || !p.treeGrid) { return; }
  19057. var i, len, rec, records = [], rt = base.getRootNodes.call($self), query = jgrid.from.call($t, rt);
  19058. // Sorting roots
  19059. query.orderBy(sortname, newDir, st, datefmt);
  19060. var roots = query.select();
  19061. // Sorting children
  19062. for (i = 0, len = roots.length; i < len; i++) {
  19063. rec = roots[i];
  19064. records.push(rec);
  19065. base.collectChildrenSortTree.call($self, records, rec, sortname, newDir, st, datefmt);
  19066. }
  19067. $.each(records, function (index) {
  19068. var id = getAccessor(this, p.localReader.id);
  19069. $($t.rows[index]).after($self.find(">tbody>tr#" + jqID(id)));
  19070. });
  19071. });
  19072. },
  19073. collectChildrenSortTree: function (records, rec, sortname, newDir, st, datefmt) {
  19074. return this.each(function () {
  19075. var $t = this, $self = $($t);
  19076. if (!$t.grid || !$t.p.treeGrid) { return; }
  19077. var i, len, child, ch = base.getNodeChildren.call($self, rec), query = jgrid.from.call($t, ch);
  19078. query.orderBy(sortname, newDir, st, datefmt);
  19079. var children = query.select();
  19080. for (i = 0, len = children.length; i < len; i++) {
  19081. child = children[i];
  19082. records.push(child);
  19083. base.collectChildrenSortTree.call($self, records, child, sortname, newDir, st, datefmt);
  19084. }
  19085. });
  19086. },
  19087. // experimental
  19088. setTreeRow: function (rowid, data) {
  19089. var success = false;
  19090. this.each(function () {
  19091. var t = this;
  19092. if (!t.grid || !t.p.treeGrid) { return; }
  19093. success = base.setRowData.call($(t), rowid, data);
  19094. });
  19095. return success;
  19096. },
  19097. delTreeNode: function (rowid, skipSelf) {
  19098. return this.each(function () {
  19099. var $t = this, p = $t.p, myright, width, res, key, rid = p.localReader.id, i, $self = $($t),
  19100. left = p.treeReader.left_field,
  19101. right = p.treeReader.right_field;
  19102. if (!$t.grid || !p.treeGrid) { return; }
  19103. var rc = p._index[rowid];
  19104. if (rc !== undefined) {
  19105. // nested
  19106. myright = parseInt(p.data[rc][right], 10);
  19107. width = myright - parseInt(p.data[rc][left], 10) + 1;
  19108. var dr = base.getFullTreeNode.call($self, p.data[rc]);
  19109. if (dr.length > 0) {
  19110. for (i = 0; i < dr.length; i++) {
  19111. if (!skipSelf || rowid !== dr[i][rid]) {
  19112. base.delRowData.call($self, dr[i][rid]);
  19113. }
  19114. }
  19115. }
  19116. if (p.treeGridModel === "nested") {
  19117. // ToDo - update grid data
  19118. res = jgrid.from.call($t, p.data)
  19119. .greater(left, myright, { stype: "integer" })
  19120. .select();
  19121. if (res.length) {
  19122. for (key in res) {
  19123. if (res.hasOwnProperty(key)) {
  19124. res[key][left] = parseInt(res[key][left], 10) - width;
  19125. }
  19126. }
  19127. }
  19128. res = jgrid.from.call($t, p.data)
  19129. .greater(right, myright, { stype: "integer" })
  19130. .select();
  19131. if (res.length) {
  19132. for (key in res) {
  19133. if (res.hasOwnProperty(key)) {
  19134. res[key][right] = parseInt(res[key][right], 10) - width;
  19135. }
  19136. }
  19137. }
  19138. }
  19139. }
  19140. });
  19141. },
  19142. addChildNode: function (nodeid, parentid, data, expandData) {
  19143. return this.each(function () {
  19144. if (!data) { return; }
  19145. var $t = this, p = $t.p, $self = $($t), getInd = base.getInd,
  19146. iconExpanded = p.treeIcons.minus + " tree-minus",
  19147. method, parentindex, parentdata, parentlevel, iRow, rowind = parentid, leaf, maxright,
  19148. expanded = p.treeReader.expanded_field, isLeaf = p.treeReader.leaf_field, level = p.treeReader.level_field,
  19149. parent = p.treeReader.parent_id_field,
  19150. left = p.treeReader.left_field,
  19151. right = p.treeReader.right_field,
  19152. loaded = p.treeReader.loaded;
  19153. if (expandData === undefined) { expandData = false; }
  19154. if (nodeid == null) {
  19155. nodeid = jgrid.randId();
  19156. }
  19157. var prow = getInd.call($self, parentid);
  19158. leaf = false;
  19159. // if not a parent we assume root
  19160. if (parentid === undefined || parentid === null || parentid === "") {
  19161. parentid = null;
  19162. rowind = null;
  19163. method = "last";
  19164. parentlevel = p.tree_root_level;
  19165. } else {
  19166. method = "after";
  19167. parentindex = p._index[parentid];
  19168. parentdata = p.data[parentindex];
  19169. parentid = parentdata[p.localReader.id];
  19170. iRow = getInd.call($self, parentid);
  19171. parentlevel = parseInt(parentdata[level], 10) + 1;
  19172. var childs = base.getFullTreeNode.call($self, parentdata);
  19173. // if there are child nodes get the last index of it
  19174. if (childs.length) {
  19175. // find the max rowIndex of the children
  19176. var iChild, iChildRow, childId;
  19177. for (iChild = 0; iChild < childs.length; iChild++) {
  19178. childId = childs[iChild][p.localReader.id];
  19179. iChildRow = getInd.call($self, childId);
  19180. if (iChildRow > iRow) {
  19181. iRow = iChildRow;
  19182. rowind = childId;
  19183. }
  19184. }
  19185. }
  19186. // if the node is leaf
  19187. if (parentdata[isLeaf]) {
  19188. leaf = true;
  19189. parentdata[expanded] = true;
  19190. //var prow = getInd.call($self, parentid);
  19191. $($t.rows[prow])
  19192. .find("span.cell-wrapperleaf").removeClass("cell-wrapperleaf").addClass("cell-wrapper")
  19193. .end()
  19194. .find("div.tree-leaf").removeClass(p.treeIcons.leaf + " tree-leaf").addClass(p.treeIcons.commonIconClass).addClass(iconExpanded);
  19195. p.data[parentindex][isLeaf] = false;
  19196. parentdata[loaded] = true;
  19197. }
  19198. }
  19199. if (data[expanded] === undefined) { data[expanded] = false; }
  19200. if (data[loaded] === undefined) { data[loaded] = false; }
  19201. data[level] = parentlevel;
  19202. if (data[isLeaf] === undefined) { data[isLeaf] = true; }
  19203. if (p.treeGridModel === "adjacency") {
  19204. data[parent] = parentid;
  19205. }
  19206. if (p.treeGridModel === "nested") {
  19207. // this method requiere more attention
  19208. var query, res, key;
  19209. //maxright = parseInt(maxright,10);
  19210. // ToDo - update grid data
  19211. if (parentid !== null) {
  19212. maxright = parseInt(parentdata[right], 10);
  19213. query = jgrid.from.call($t, p.data);
  19214. query = query.greaterOrEquals(right, maxright, { stype: "integer" });
  19215. res = query.select();
  19216. if (res.length) {
  19217. for (key in res) {
  19218. if (res.hasOwnProperty(key)) {
  19219. res[key][left] = res[key][left] > maxright ? parseInt(res[key][left], 10) + 2 : res[key][left];
  19220. res[key][right] = res[key][right] >= maxright ? parseInt(res[key][right], 10) + 2 : res[key][right];
  19221. }
  19222. }
  19223. }
  19224. data[left] = maxright;
  19225. data[right] = maxright + 1;
  19226. } else {
  19227. maxright = parseInt(base.getCol.call($self, right, false, "max"), 10);
  19228. res = jgrid.from.call($t, p.data)
  19229. .greater(left, maxright, { stype: "integer" })
  19230. .select();
  19231. if (res.length) {
  19232. for (key in res) {
  19233. if (res.hasOwnProperty(key)) {
  19234. res[key][left] = parseInt(res[key][left], 10) + 2;
  19235. }
  19236. }
  19237. }
  19238. res = jgrid.from.call($t, p.data)
  19239. .greater(right, maxright, { stype: "integer" })
  19240. .select();
  19241. if (res.length) {
  19242. for (key in res) {
  19243. if (res.hasOwnProperty(key)) {
  19244. res[key][right] = parseInt(res[key][right], 10) + 2;
  19245. }
  19246. }
  19247. }
  19248. data[left] = maxright + 1;
  19249. data[right] = maxright + 2;
  19250. }
  19251. }
  19252. if (parentid === null || base.isNodeLoaded.call($self, parentdata) || leaf) {
  19253. base.addRowData.call($self, nodeid, data, method, rowind);
  19254. }
  19255. if (parentdata && !parentdata[expanded] && expandData) {
  19256. $($t.rows[prow])
  19257. .find("div.treeclick")
  19258. .click();
  19259. }
  19260. });
  19261. }
  19262. });
  19263. // end module grid.treegrid
  19264. /**
  19265. * jqDnR - Minimalistic Drag'n'Resize for jQuery.
  19266. *
  19267. * Copyright (c) 2007 Brice Burgess <bhb@iceburg.net>, http://www.iceburg.net
  19268. * Licensed under the MIT License:
  19269. * http://www.opensource.org/licenses/mit-license.php
  19270. *
  19271. * $Version: 2007.08.19 +r2
  19272. * Updated by Oleg Kiriljuk to support touch devices
  19273. * Copyright (c) 2014-2018, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  19274. */
  19275. // begin module jqdnr
  19276. var namespace = ".jqGrid", mouseDown = "mousedown", mouseMove = "mousemove", mouseUp = "mouseup",
  19277. getMouseCoordinates = function (e) {
  19278. var orgEvent = e.originalEvent, touches = orgEvent.targetTouches;
  19279. if (touches) {
  19280. touches = touches[0];
  19281. return { x: touches.pageX, y: touches.pageY };
  19282. }
  19283. return { x: e.pageX, y: e.pageY };
  19284. },
  19285. jqDnR = {
  19286. drag: function (e) {
  19287. var d = e.data, $mainDialog = d.e, dnrMainDialog = d.dnr, $alsoResize = d.ar, dnrAlsoResize = d.dnrAr,
  19288. xy = getMouseCoordinates(e);
  19289. if (dnrMainDialog.k === "move") {
  19290. $mainDialog.css({
  19291. left: dnrMainDialog.X + xy.x - dnrMainDialog.pX,
  19292. top: dnrMainDialog.Y + xy.y - dnrMainDialog.pY
  19293. });
  19294. } else {
  19295. $mainDialog.css({
  19296. width: Math.max(xy.x - dnrMainDialog.pX + dnrMainDialog.W, 0),
  19297. height: Math.max(xy.y - dnrMainDialog.pY + dnrMainDialog.H, 0)
  19298. });
  19299. if (dnrAlsoResize) {
  19300. $alsoResize.css({
  19301. width: Math.max(xy.x - dnrAlsoResize.pX + dnrAlsoResize.W, 0),
  19302. height: Math.max(xy.y - dnrAlsoResize.pY + dnrAlsoResize.H, 0)
  19303. });
  19304. }
  19305. }
  19306. return false;
  19307. },
  19308. stop: function () {
  19309. //$mainDialog.css("opacity", dnr.o);
  19310. $(document).off(mouseMove, jqDnR.drag).off(mouseUp, jqDnR.stop);
  19311. }
  19312. },
  19313. init = function ($this, handle, actionName, alsoResize) {
  19314. return $this.each(function () {
  19315. handle = handle ? $(handle, $this) : $this;
  19316. handle.on(mouseDown, { e: $this, k: actionName }, function (e) {
  19317. var d = e.data, p = {}, $inputDatePicker, $mainDialog, dnrMainDialog, $alsoResize, dnrAlsoResize,
  19318. getCssProp = function ($elem, propertyName) {
  19319. return parseInt($elem.css(propertyName), 10) || false;
  19320. },
  19321. getMainCssProp = function (propertyName) {
  19322. return getCssProp($mainDialog, propertyName);
  19323. },
  19324. getAlsoResizeCssProp = function (propertyName) {
  19325. return getCssProp($alsoResize, propertyName);
  19326. },
  19327. xy = getMouseCoordinates(e),
  19328. eventData;
  19329. if ($(e.target).hasClass("ui-jqdialog-titlebar-close") || $(e.target).parent().hasClass("ui-jqdialog-titlebar-close")) {
  19330. //$(e.target).click();
  19331. return;
  19332. }
  19333. $mainDialog = d.e;
  19334. $alsoResize = alsoResize ? $(alsoResize) : false;
  19335. // attempt utilization of dimensions plugin to fix IE issues
  19336. if ($mainDialog.css("position") !== "relative") {
  19337. try {
  19338. // ???? probably one want to GET position and save it in p ?
  19339. // the current implementation use always p = {}
  19340. // probably one mean some additional work together with Dimensions Plugin (dimensions.js)
  19341. $mainDialog.position(p);
  19342. } catch (ignore) { }
  19343. }
  19344. dnrMainDialog = {
  19345. X: p.left || getMainCssProp("left") || 0,
  19346. Y: p.top || getMainCssProp("top") || 0,
  19347. W: getMainCssProp("width") || $mainDialog[0].scrollWidth || 0,
  19348. H: getMainCssProp("height") || $mainDialog[0].scrollHeight || 0,
  19349. pX: xy.x,
  19350. pY: xy.y,
  19351. k: d.k
  19352. //o:$mainDialog.css("opacity")
  19353. };
  19354. // also resize
  19355. if ($alsoResize && d.k !== "move") {
  19356. dnrAlsoResize = {
  19357. X: p.left || getAlsoResizeCssProp("left") || 0,
  19358. Y: p.top || getAlsoResizeCssProp("top") || 0,
  19359. W: $alsoResize[0].offsetWidth || getAlsoResizeCssProp("width") || 0,
  19360. H: $alsoResize[0].offsetHeight || getAlsoResizeCssProp("height") || 0,
  19361. pX: xy.x,
  19362. pY: xy.y,
  19363. k: d.k
  19364. };
  19365. } else {
  19366. dnrAlsoResize = false;
  19367. }
  19368. //E.css({opacity:0.8});
  19369. $inputDatePicker = $mainDialog.find("input.hasDatepicker");
  19370. if ($inputDatePicker.length > 0) {
  19371. try {
  19372. $inputDatePicker.datepicker("hide");
  19373. } catch (ignore) { }
  19374. }
  19375. eventData = {
  19376. e: $mainDialog,
  19377. dnr: dnrMainDialog,
  19378. ar: $alsoResize,
  19379. dnrAr: dnrAlsoResize
  19380. };
  19381. $(document).on(mouseMove, eventData, jqDnR.drag);
  19382. $(document).on(mouseUp, eventData, jqDnR.stop);
  19383. return false;
  19384. });
  19385. });
  19386. };
  19387. // navigator.maxTouchPoints == 2, navigator.msMaxTouchPoints
  19388. // https://msdn.microsoft.com/en-us/library/ie/dn304886(v=vs.85).aspx
  19389. if (window.PointerEvent) {
  19390. mouseDown += namespace + " pointerdown" + namespace;
  19391. mouseMove += namespace + " pointermove" + namespace;
  19392. mouseUp += namespace + " pointerup" + namespace;
  19393. } else if (window.MSPointerEvent) {
  19394. mouseDown += namespace + " mspointerdown" + namespace;
  19395. mouseMove += namespace + " mspointermove" + namespace;
  19396. mouseUp += namespace + " mspointerup";
  19397. } else { //if (Object.prototype.hasOwnProperty.call(document, "ontouchend")) { or "ontouchstart" in document.documentElement or "ontouchstart" in window
  19398. mouseDown += namespace + " touchstart" + namespace;
  19399. mouseMove += namespace + " touchmove" + namespace;
  19400. mouseUp += namespace + " touchend" + namespace;
  19401. }
  19402. $.jqDnR = jqDnR;
  19403. $.fn.jqDrag = function (handle) {
  19404. return init(this, handle, "move");
  19405. };
  19406. $.fn.jqResize = function (handle, alsoResize) {
  19407. return init(this, handle, "resize", alsoResize);
  19408. };
  19409. // end module jqdnr
  19410. /**
  19411. * jqModal - Minimalist Modaling with jQuery
  19412. * (http://dev.iceburg.net/jquery/jqmodal/)
  19413. *
  19414. * Copyright (c) 2007,2008 Brice Burgess <bhb@iceburg.net>
  19415. * Dual licensed under the MIT and GPL licenses:
  19416. * http://www.opensource.org/licenses/mit-license.php
  19417. * http://www.gnu.org/licenses/gpl.html
  19418. *
  19419. * $Version: 07/06/2008 +r13
  19420. * Changed by Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  19421. * Copyright (c) 2014-2018, Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  19422. */
  19423. // begin module jqmodal
  19424. var jqmHashLength = 0,
  19425. jqmHash,
  19426. createdModals = [],
  19427. setFocusOnFirstVisibleInput = function (h) {
  19428. try {
  19429. $(":input:visible", h.w).first().focus();
  19430. } catch (ignore) {}
  19431. },
  19432. setFocus = function (h) {
  19433. setFocusOnFirstVisibleInput(h);
  19434. },
  19435. keyOrMouseEventHandler = function (e) {
  19436. var activeModal = jqmHash[createdModals[createdModals.length - 1]],
  19437. modal = !$(e.target).parents(".jqmID" + activeModal.s)[0],
  19438. targetOffset = $(e.target).offset(),
  19439. eX = e.pageX !== undefined ? e.pageX : targetOffset.left,
  19440. eY = e.pageY !== undefined ? e.pageY : targetOffset.top,
  19441. isEventInsideOfModal = function () {
  19442. var isInside = false;
  19443. $(".jqmID" + activeModal.s).each(function () {
  19444. var $self = $(this), offset = $self.offset();
  19445. // mouse event have e.pageX and e.pageY
  19446. // keyboard event have e.type == "keydown" or "keypress",
  19447. // e.pageX and e.pageY are undefined and one can use
  19448. // $(e.target).offset()
  19449. if (offset.top <= eY && eY <= offset.top + $self.height() &&
  19450. offset.left <= eX && eX <= offset.left + $self.width()) {
  19451. isInside = true;
  19452. return false; // stop enumeration
  19453. }
  19454. });
  19455. return isInside;
  19456. };
  19457. if (e.type !== "mousedown" && isEventInsideOfModal()) {
  19458. // allows keyboard events inside of the modal
  19459. return true;
  19460. }
  19461. if (e.type === "mousedown" && modal) {
  19462. if (isEventInsideOfModal()) {
  19463. modal = false;
  19464. }
  19465. if (modal && !$(e.target).is(":input")) {
  19466. setFocusOnFirstVisibleInput(activeModal);
  19467. }
  19468. }
  19469. return !modal;
  19470. },
  19471. bindOrUnbindEvents = function (bindOrUnbind) {
  19472. // bindOrUnbind is either "bind" or "unbind" string
  19473. $(document)[bindOrUnbind]("keypress keydown mousedown", keyOrMouseEventHandler);
  19474. },
  19475. registerHideOrShow = function (w, trigger, key) {
  19476. return w.each(function () {
  19477. var jqm = this._jqm;
  19478. $(trigger).each(function () {
  19479. if (!this[key]) {
  19480. this[key] = [];
  19481. $(this).click(function () {
  19482. var i, method, propertyName, methods = ["jqmShow", "jqmHide"];
  19483. for (i = 0; i < methods.length; i++) {
  19484. method = methods[i];
  19485. for (propertyName in this[method]) {
  19486. if (this[method].hasOwnProperty(propertyName) && jqmHash[this[method][propertyName]]) {
  19487. jqmHash[this[method][propertyName]].w[method](this);
  19488. }
  19489. }
  19490. }
  19491. return false;
  19492. });
  19493. }
  19494. this[key].push(jqm);
  19495. });
  19496. });
  19497. };
  19498. $.fn.jqm = function (o) {
  19499. var p = {
  19500. overlay: 50,
  19501. closeoverlay: false,
  19502. overlayClass: "jqmOverlay",
  19503. closeClass: "jqmClose",
  19504. trigger: ".jqModal",
  19505. ajax: false,
  19506. ajaxText: "",
  19507. target: false,
  19508. modal: false,
  19509. toTop: false,
  19510. onShow: false,
  19511. onHide: false,
  19512. onLoad: false
  19513. };
  19514. return this.each(function () {
  19515. if (this._jqm) {
  19516. jqmHash[this._jqm].c = $.extend({}, jqmHash[this._jqm].c, o);
  19517. return jqmHash[this._jqm].c;
  19518. }
  19519. jqmHashLength++;
  19520. this._jqm = jqmHashLength;
  19521. jqmHash[jqmHashLength] = {
  19522. // comment from https://github.com/briceburg/jqModal/blob/master/jqModal.js
  19523. // hash object;
  19524. // w: (jQuery object) The modal element
  19525. // c: (object) The modal's options object
  19526. // o: (jQuery object) The overlay element
  19527. // t: (DOM object) The triggering element
  19528. c: $.extend(p, $.jqm.params, o),
  19529. a: false,
  19530. w: $(this).addClass("jqmID" + jqmHashLength),
  19531. s: jqmHashLength // used as id too
  19532. };
  19533. if (p.trigger) {
  19534. $(this).jqmAddTrigger(p.trigger);
  19535. }
  19536. });
  19537. };
  19538. $.fn.jqmAddClose = function (trigger) {
  19539. return registerHideOrShow(this, trigger, "jqmHide");
  19540. };
  19541. $.fn.jqmAddTrigger = function (trigger) {
  19542. return registerHideOrShow(this, trigger, "jqmShow");
  19543. };
  19544. $.fn.jqmShow = function (trigger) {
  19545. return this.each(function () {
  19546. $.jqm.open(this._jqm, trigger);
  19547. });
  19548. };
  19549. $.fn.jqmHide = function (trigger) {
  19550. return this.each(function () {
  19551. $.jqm.close(this._jqm, trigger);
  19552. });
  19553. };
  19554. $.jqm = {
  19555. hash: {},
  19556. open: function (s, trigger) {
  19557. var h = jqmHash[s], $overlay, target, url,
  19558. options = h.c, parentOffset = h.w.parent().offset(), left, top,
  19559. cc = "." + options.closeClass,
  19560. z = (parseInt(h.w.css("z-index"), 10));
  19561. z = (z > 0) ? z : 3000;
  19562. $overlay = $("<div></div>").css({
  19563. height: "100%",
  19564. width: "100%",
  19565. position: "fixed",
  19566. left: 0,
  19567. top: 0,
  19568. "z-index": z - 1,
  19569. opacity: options.overlay / 100
  19570. });
  19571. if (h.a) {
  19572. return false;
  19573. }
  19574. h.t = trigger;
  19575. h.a = true;
  19576. h.w.css("z-index", z);
  19577. if ($(h.w[0].ownerDocument).data("ui-dialog-overlays")) {
  19578. h.w.addClass("ui-dialog"); // hack to allow input inside of jQuery UI modal
  19579. }
  19580. if (options.modal) {
  19581. if (!createdModals[0]) {
  19582. setTimeout(function () {
  19583. bindOrUnbindEvents("bind");
  19584. }, 1);
  19585. }
  19586. createdModals.push(s);
  19587. } else if (options.overlay > 0) {
  19588. if (options.closeoverlay) {
  19589. h.w.jqmAddClose($overlay);
  19590. }
  19591. } else {
  19592. $overlay = false;
  19593. }
  19594. h.o = $overlay ? $overlay.addClass(options.overlayClass).prependTo("body") : false;
  19595. if (options.ajax) {
  19596. target = options.target || h.w;
  19597. url = options.ajax;
  19598. target = (typeof target === "string") ? $(target, h.w) : $(target);
  19599. url = (url.substr(0, 1) === "@") ? $(trigger).attr(url.substring(1)) : url;
  19600. target.html(options.ajaxText)
  19601. .load(url, function () {
  19602. if (options.onLoad) {
  19603. options.onLoad.call(this, h);
  19604. }
  19605. if (cc) {
  19606. h.w.jqmAddClose($(cc, h.w));
  19607. }
  19608. setFocus(h);
  19609. });
  19610. } else if (cc) {
  19611. h.w.jqmAddClose($(cc, h.w));
  19612. }
  19613. if (options.toTop && h.o) {
  19614. parentOffset = h.w.parent().offset();
  19615. left = parseFloat(h.w.css("left") || 0);
  19616. top = parseFloat(h.w.css("top") || 0);
  19617. h.w.before('<span id="jqmP' + h.w[0]._jqm + '"></span>')
  19618. .insertAfter(h.o);
  19619. h.w.css({ top: parentOffset.top + top, left: parentOffset.left + left });
  19620. }
  19621. if (options.onShow) {
  19622. options.onShow(h);
  19623. } else {
  19624. h.w.show();
  19625. }
  19626. setFocus(h);
  19627. return false;
  19628. },
  19629. close: function (s) {
  19630. var h = jqmHash[s];
  19631. if (!h.a) {
  19632. return false;
  19633. }
  19634. h.a = false;
  19635. if (createdModals[0]) {
  19636. createdModals.pop();
  19637. if (!createdModals[0]) {
  19638. bindOrUnbindEvents("unbind");
  19639. }
  19640. }
  19641. if (h.c.toTop && h.o) {
  19642. $("#jqmP" + h.w[0]._jqm)
  19643. .after(h.w)
  19644. .remove();
  19645. }
  19646. if (h.c.onHide) {
  19647. h.c.onHide(h);
  19648. } else {
  19649. h.w.hide();
  19650. if (h.o) {
  19651. h.o.remove();
  19652. }
  19653. }
  19654. return false;
  19655. },
  19656. params: {}
  19657. };
  19658. jqmHash = $.jqm.hash;
  19659. // end module jqmodal
  19660. /**
  19661. * formatter for values but most of the values if for jqGrid
  19662. * Some of this was inspired and based on how YUI does the table datagrid but in jQuery fashion
  19663. * we are trying to keep it as light as possible
  19664. * Joshua Burnett josh@9ci.com
  19665. * http://www.greenbill.com
  19666. *
  19667. * Changes from Tony Tomov tony@trirand.com
  19668. * Changed by Oleg Kiriljuk, oleg.kiriljuk@ok-soft-gmbh.com
  19669. * Dual licensed under the MIT and GPL licenses:
  19670. * http://www.opensource.org/licenses/mit-license.php
  19671. * http://www.gnu.org/licenses/gpl-2.0.html
  19672. *
  19673. **/
  19674. // begin module jquery.fmatter
  19675. $.fmatter = $.fmatter || {};
  19676. var fmatter = $.fmatter,
  19677. getOptionByName = function (colModel, name) {
  19678. var option = colModel.formatoptions || {};
  19679. if (option.hasOwnProperty(name)) {
  19680. return option[name];
  19681. } else {
  19682. return (colModel.editoptions || {})[name];
  19683. }
  19684. },
  19685. encodeAttr = function (v) {
  19686. return String(v).replace(/\'/g, "&#39;");
  19687. },
  19688. parseCheckboxOptions = function (options) {
  19689. var colModel = options.colModel || options.cm, checked, unchecked,
  19690. title = colModel.title !== false ?
  19691. " title='" + encodeAttr(options.colName || colModel.name) + "'" :
  19692. "",
  19693. getOption = function (name) {
  19694. return getOptionByName(colModel, name);
  19695. },
  19696. checkedClasses = getOption("checkedClass"),
  19697. uncheckedClasses = getOption("uncheckedClass"),
  19698. value = getOption("value"),
  19699. yes = typeof value === "string" ? (value.split(":")[0] || "Yes") : "Yes",
  19700. no = typeof value === "string" ? (value.split(":")[1] || "No") : "No",
  19701. buildCheckbox = function (classes) {
  19702. return "<i class='" + encodeAttr(classes) + "'" + title + "></i>";
  19703. },
  19704. disabled = getOption("disabled");
  19705. if (disabled === undefined) {
  19706. disabled = jgrid.formatter.checkbox.disabled;
  19707. }
  19708. var checkedIcon = base.getIconRes.call(this, "checkbox.checked"),
  19709. checkedIconClasses = base.getIconRes.call(this, "checkbox.checkedClasses"),
  19710. uncheckedIcon = base.getIconRes.call(this, "checkbox.unchecked");
  19711. if (disabled === true && (checkedClasses || uncheckedClasses || checkedIcon || uncheckedIcon)) {
  19712. checked = buildCheckbox(checkedClasses || checkedIcon);
  19713. unchecked = buildCheckbox(uncheckedClasses || uncheckedIcon);
  19714. checkedClasses = checkedIconClasses ? checkedIconClasses : checkedClasses || checkedIcon;
  19715. } else {
  19716. checkedClasses = "";
  19717. title += disabled === true ? " disabled='disabled'" : "";
  19718. checked = "<input type='checkbox' checked='checked'" + title + " />";
  19719. unchecked = "<input type='checkbox'" + title + " />";
  19720. }
  19721. return {
  19722. checkedClasses: checkedClasses,
  19723. checked: checked,
  19724. unchecked: unchecked,
  19725. yes: yes,
  19726. no: no
  19727. };
  19728. },
  19729. // http://jsperf.com/regex-vs-indexof-vs-in/12
  19730. /*yesObject = Object.create(null, {
  19731. 1: { value: 1 },
  19732. x: { value: 1 },
  19733. "true": { value: 1 },
  19734. yes: { value: 1 },
  19735. on: { value: 1 }
  19736. }),
  19737. noObject = Object.create(null, {
  19738. 0: { value: 1 },
  19739. "false": { value: 1 },
  19740. no: { value: 1 },
  19741. off: { value: 1 }
  19742. });*/
  19743. // one can use typeof Object.create != "function" and use either
  19744. // Object.create or simple object firm, but the performance differences
  19745. // are so low, that the compatibility to IE8 is more important
  19746. yesObject = { 1: 1, x: 1, "true": 1, yes: 1, y: 1, on: 1 },
  19747. noObject = { 0: 1, "false": 1, no: 1, n: 1, off: 1 };
  19748. $.extend(true, jgrid, {
  19749. formatter: { // setting common formatter settings, which are independent from the language and locale
  19750. date: {
  19751. parseRe: /[#%\\\/:_;.,\t\s\-]/,
  19752. masks: {
  19753. ISO8601Long: "Y-m-d H:i:s",
  19754. ISO8601Short: "Y-m-d",
  19755. SortableDateTime: "Y-m-d\\TH:i:s",
  19756. UniversalSortableDateTime: "Y-m-d H:i:sO"
  19757. },
  19758. reformatAfterEdit: true,
  19759. userLocalTime: false
  19760. },
  19761. baseLinkUrl: "",
  19762. showAction: "",
  19763. target: "",
  19764. checkbox: { disabled: true, defaultValue: false },
  19765. idName: "id"
  19766. },
  19767. cmTemplate: {
  19768. integerStr: {
  19769. formatter: "integer", align: "right", sorttype: "integer",
  19770. searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"] }
  19771. },
  19772. integer: {
  19773. formatter: "integer", align: "right", sorttype: "integer",
  19774. convertOnSave: function (options) {
  19775. var nData = options.newValue;
  19776. return isNaN(nData) ? nData : parseInt(nData, 10);
  19777. },
  19778. searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"] }
  19779. },
  19780. numberStr: {
  19781. formatter: "number", align: "right", sorttype: "number",
  19782. searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"] }
  19783. },
  19784. number: {
  19785. formatter: "number", align: "right", sorttype: "number",
  19786. convertOnSave: function (options) {
  19787. var nData = options.newValue;
  19788. return isNaN(nData) ? nData : parseFloat(nData);
  19789. },
  19790. searchoptions: { sopt: ["eq", "ne", "lt", "le", "gt", "ge"] }
  19791. },
  19792. booleanCheckbox: {
  19793. align: "center", formatter: "checkbox", sorttype: "boolean",
  19794. edittype: "checkbox", editoptions: { value: "true:false", defaultValue: "false" },
  19795. convertOnSave: function (options) {
  19796. var newValue = options.newValue,
  19797. checkboxOptions = parseCheckboxOptions.call(this, options),
  19798. lowerCaseNewData = String(newValue).toLowerCase();
  19799. if (yesObject[lowerCaseNewData] || lowerCaseNewData === checkboxOptions.yes.toLowerCase()) {
  19800. newValue = true;
  19801. } else if (noObject[lowerCaseNewData] || lowerCaseNewData === checkboxOptions.no.toLowerCase()) {
  19802. newValue = false;
  19803. }
  19804. return newValue;
  19805. },
  19806. stype: "checkbox", searchoptions: { sopt: ["eq"], value: "true:false" }
  19807. },
  19808. // TODO: add cmTemplate for currency and date
  19809. actions: function () {
  19810. var p = this.p;
  19811. return {
  19812. formatter: "actions",
  19813. width: (p != null && (base.isInCommonIconClass.call(this, "fa") || base.isInCommonIconClass.call(this, "glyphicon")) ?
  19814. ($(this).jqGrid("isBootstrapGuiStyle") ? 45 : 39) : 40) + (jgrid.cellWidth() ? 5 : 0),
  19815. align: "center",
  19816. label: "",
  19817. autoResizable: false,
  19818. title: false,
  19819. frozen: true,
  19820. fixed: true,
  19821. hidedlg: true,
  19822. resizable: false,
  19823. sortable: false,
  19824. search: false,
  19825. editable: false,
  19826. viewable: false
  19827. };
  19828. }
  19829. }
  19830. });
  19831. jgrid.cmTemplate.booleanCheckboxFa = jgrid.cmTemplate.booleanCheckbox;
  19832. //opts can be id:row id for the row, rowdata:the data for the row, colmodel:the column model for this column
  19833. //example {id:1234,}
  19834. $.extend(fmatter, {
  19835. // one can consider to use $.type instead of some functions below (see http://api.jquery.com/jQuery.type/)
  19836. isObject: function (o) {
  19837. return (o && (typeof o === "object" || $.isFunction(o))) || false;
  19838. },
  19839. isNumber: function (o) {
  19840. // probably Number.isFinite can be used instead.
  19841. return typeof o === "number" && isFinite(o); // return false for +infinity, -infinity, or NaN
  19842. },
  19843. isValue: function (o) {
  19844. return (this.isObject(o) || typeof o === "string" || this.isNumber(o) || typeof o === "boolean");
  19845. },
  19846. isEmpty: function (o) {
  19847. if (typeof o !== "string" && this.isValue(o)) {
  19848. return false;
  19849. }
  19850. if (!this.isValue(o)) {
  19851. return true;
  19852. }
  19853. o = $.trim(o).replace(/&nbsp;/ig, "").replace(/&#160;/ig, "");
  19854. return o === "";
  19855. },
  19856. NumberFormat: function (nData, opts) {
  19857. var isNumber = fmatter.isNumber;
  19858. if (!isNumber(nData)) {
  19859. nData *= 1;
  19860. }
  19861. if (isNumber(nData)) {
  19862. var bNegative = (nData < 0);
  19863. var sOutput = String(nData);
  19864. var sDecimalSeparator = opts.decimalSeparator || ".";
  19865. var nDotIndex;
  19866. if (isNumber(opts.decimalPlaces)) {
  19867. // Round to the correct decimal place
  19868. var nDecimalPlaces = opts.decimalPlaces;
  19869. // we use rounding described in http://www.jacklmoore.com/notes/rounding-in-javascript/
  19870. sOutput = String(Number(Math.round(nData + "e" + nDecimalPlaces) + "e-" + nDecimalPlaces));
  19871. nDotIndex = sOutput.lastIndexOf(".");
  19872. if (nDecimalPlaces > 0) {
  19873. // Add the decimal separator
  19874. if (nDotIndex < 0) {
  19875. sOutput += sDecimalSeparator;
  19876. nDotIndex = sOutput.length - 1;
  19877. } else if (sDecimalSeparator !== ".") { // Replace the "."
  19878. sOutput = sOutput.replace(".", sDecimalSeparator);
  19879. }
  19880. // Add missing zeros
  19881. while ((sOutput.length - 1 - nDotIndex) < nDecimalPlaces) {
  19882. sOutput += "0";
  19883. }
  19884. }
  19885. }
  19886. if (opts.thousandsSeparator) {
  19887. var sThousandsSeparator = opts.thousandsSeparator;
  19888. nDotIndex = sOutput.lastIndexOf(sDecimalSeparator);
  19889. nDotIndex = (nDotIndex > -1) ? nDotIndex : sOutput.length;
  19890. // we cut the part after the point for integer numbers
  19891. // it will prevent storing/restoring of wrong numbers during inline editing
  19892. var sNewOutput = opts.decimalSeparator === undefined ? "" : sOutput.substring(nDotIndex);
  19893. var nCount = -1, i;
  19894. for (i = nDotIndex; i > 0; i--) {
  19895. nCount++;
  19896. if ((nCount % 3 === 0) && (i !== nDotIndex) && (!bNegative || (i > 1))) {
  19897. sNewOutput = sThousandsSeparator + sNewOutput;
  19898. }
  19899. sNewOutput = sOutput.charAt(i - 1) + sNewOutput;
  19900. }
  19901. sOutput = sNewOutput;
  19902. }
  19903. return sOutput;
  19904. }
  19905. return nData;
  19906. }
  19907. });
  19908. var $FnFmatter = function (formatType, cellval, opts, rwd, act) {
  19909. // build main options before element iteration
  19910. var v = cellval;
  19911. opts = $.extend({}, getGridRes.call($(this), "formatter"), opts);
  19912. try {
  19913. v = $.fn.fmatter[formatType].call(this, cellval, opts, rwd, act);
  19914. } catch (ignore) { }
  19915. return v;
  19916. };
  19917. $.fn.fmatter = $FnFmatter;
  19918. $FnFmatter.getCellBuilder = function (formatType, opts, act) {
  19919. var cellBuilder = $.fn.fmatter[formatType] != null ? $.fn.fmatter[formatType].getCellBuilder : null;
  19920. return $.isFunction(cellBuilder) ?
  19921. cellBuilder.call(this, $.extend({}, getGridRes.call($(this), "formatter"), opts), act) :
  19922. null;
  19923. };
  19924. $FnFmatter.defaultFormat = function (cellval, opts) {
  19925. return (fmatter.isValue(cellval) && cellval !== "") ? cellval : opts.defaultValue || "&#160;";
  19926. };
  19927. var defaultFormat = $FnFmatter.defaultFormat,
  19928. formatCheckboxValue = function (cellValue, checkboxOptions, colModel) {
  19929. if (cellValue === undefined || fmatter.isEmpty(cellValue)) {
  19930. var defaultValue = getOptionByName(colModel, "defaultValue");
  19931. if (defaultValue === undefined) {
  19932. defaultValue = checkboxOptions.no;
  19933. }
  19934. cellValue = defaultValue;
  19935. }
  19936. // see http://jsperf.com/regex-vs-indexof-vs-in/12
  19937. cellValue = String(cellValue).toLowerCase();
  19938. return yesObject[cellValue] || cellValue === checkboxOptions.yes.toLowerCase() ?
  19939. checkboxOptions.checked :
  19940. checkboxOptions.unchecked;
  19941. };
  19942. $FnFmatter.email = function (cellval, opts) {
  19943. if (!fmatter.isEmpty(cellval)) {
  19944. return "<a href='mailto:" + encodeAttr(cellval) + "'>" + cellval + "</a>";
  19945. }
  19946. return defaultFormat(cellval, opts);
  19947. };
  19948. $FnFmatter.checkbox = function (cellValue, options) {
  19949. var checkboxOptions = parseCheckboxOptions.call(this, options);
  19950. return formatCheckboxValue(cellValue, checkboxOptions, options.colModel);
  19951. };
  19952. $FnFmatter.checkbox.getCellBuilder = function (options) {
  19953. var checkboxOptions, colModel = options.colModel;
  19954. options.colName = options.colName || this.p.colNames[options.pos];
  19955. checkboxOptions = parseCheckboxOptions.call(this, options);
  19956. return function (cellValue) {
  19957. return formatCheckboxValue(cellValue, checkboxOptions, colModel);
  19958. };
  19959. };
  19960. $FnFmatter.checkbox.unformat = function (cellValue, options, elem) {
  19961. var checkboxOptions = parseCheckboxOptions.call(this, options),
  19962. $elem = $(elem);
  19963. return (checkboxOptions.checkedClasses ?
  19964. jgrid.hasAllClasses($elem.children("i,svg"), checkboxOptions.checkedClasses) :
  19965. $elem.children("input").is(":checked")) ?
  19966. checkboxOptions.yes :
  19967. checkboxOptions.no;
  19968. };
  19969. $FnFmatter.checkboxFontAwesome4 = $FnFmatter.checkbox;
  19970. $FnFmatter.checkboxFontAwesome4.getCellBuilder = $FnFmatter.checkbox.getCellBuilder;
  19971. $FnFmatter.checkboxFontAwesome4.unformat = $FnFmatter.checkbox.unformat;
  19972. $FnFmatter.link = function (cellval, opts) {
  19973. var colModel = opts.colModel, target = "", op = { target: opts.target };
  19974. if (colModel != null) {
  19975. op = $.extend({}, op, colModel.formatoptions || {});
  19976. }
  19977. if (op.target) { target = "target=" + op.target; }
  19978. if (!fmatter.isEmpty(cellval)) {
  19979. return "<a " + target + " href='" + encodeAttr(cellval) + "'>" + cellval + "</a>";
  19980. }
  19981. return defaultFormat(cellval, op);
  19982. };
  19983. $FnFmatter.showlink = function (cellval, opts, rowData) {
  19984. var self = this, colModel = opts.colModel,
  19985. op = {
  19986. baseLinkUrl: opts.baseLinkUrl,
  19987. showAction: opts.showAction,
  19988. addParam: opts.addParam || "",
  19989. target: opts.target,
  19990. idName: opts.idName,
  19991. hrefDefaultValue: "#"
  19992. },
  19993. target = "",
  19994. idUrl,
  19995. idParam,
  19996. addParam,
  19997. getOptionValue = function (option) {
  19998. return $.isFunction(option) ?
  19999. option.call(self, {
  20000. cellValue: cellval,
  20001. rowid: opts.rowId,
  20002. rowData: rowData,
  20003. options: op
  20004. }) :
  20005. option || "";
  20006. };
  20007. if (colModel != null) {
  20008. op = $.extend({}, op, colModel.formatoptions || {});
  20009. }
  20010. if (op.target) {
  20011. target = "target=" + getOptionValue(op.target);
  20012. }
  20013. idUrl = getOptionValue(op.baseLinkUrl) + getOptionValue(op.showAction);
  20014. idParam = op.idName ? encodeURIComponent(getOptionValue(op.idName)) + "=" + encodeURIComponent(getOptionValue(op.rowId) || opts.rowId) : "";
  20015. addParam = getOptionValue(op.addParam);
  20016. if (typeof addParam === "object" && addParam !== null) {
  20017. // add "&" only in case of usage object for of addParam
  20018. addParam = (idParam !== "" ? "&" : "") + $.param(addParam);
  20019. }
  20020. idUrl += !idParam && !addParam ? "" : "?" + idParam + addParam;
  20021. if (idUrl === "") {
  20022. idUrl = getOptionValue(op.hrefDefaultValue);
  20023. }
  20024. if (typeof cellval === "string" || fmatter.isNumber(cellval) || $.isFunction(op.cellValue)) {
  20025. //add this one even if cellval is blank string
  20026. return "<a " + target + " href='" + encodeAttr(idUrl) + "'>" +
  20027. ($.isFunction(op.cellValue) ? getOptionValue(op.cellValue) : cellval) +
  20028. "</a>";
  20029. }
  20030. // the code below will be called typically for undefined cellval or
  20031. // if cellval have null value or some other unclear value like an object
  20032. // and no cellValue callback function are defined "to decode" the value
  20033. return defaultFormat(cellval, op);
  20034. };
  20035. $FnFmatter.showlink.getCellBuilder = function (opts1) {
  20036. var op = {
  20037. baseLinkUrl: opts1.baseLinkUrl,
  20038. showAction: opts1.showAction,
  20039. addParam: opts1.addParam || "",
  20040. target: opts1.target,
  20041. idName: opts1.idName,
  20042. hrefDefaultValue: "#"
  20043. },
  20044. colModel = opts1.colModel;
  20045. if (colModel != null) {
  20046. op = $.extend({}, op, colModel.formatoptions || {});
  20047. }
  20048. return function (cellval, opts, rowData) {
  20049. var self = this, rowid = opts.rowId, target = "", idUrl, idParam, addParam,
  20050. getOptionValue = function (option) {
  20051. return $.isFunction(option) ?
  20052. option.call(self, {
  20053. cellValue: cellval,
  20054. rowid: rowid,
  20055. rowData: rowData,
  20056. options: op
  20057. }) :
  20058. option || "";
  20059. };
  20060. if (op.target) {
  20061. target = "target=" + getOptionValue(op.target);
  20062. }
  20063. idUrl = getOptionValue(op.baseLinkUrl) + getOptionValue(op.showAction);
  20064. idParam = op.idName ? encodeURIComponent(getOptionValue(op.idName)) + "=" + encodeURIComponent(getOptionValue(rowid) || opts.rowId) : "";
  20065. addParam = getOptionValue(op.addParam);
  20066. if (typeof addParam === "object" && addParam !== null) {
  20067. // add "&" only in case of usage object for of addParam
  20068. addParam = (idParam !== "" ? "&" : "") + $.param(addParam);
  20069. }
  20070. idUrl += !idParam && !addParam ? "" : "?" + idParam + addParam;
  20071. if (idUrl === "") {
  20072. idUrl = getOptionValue(op.hrefDefaultValue);
  20073. }
  20074. if (typeof cellval === "string" || fmatter.isNumber(cellval) || $.isFunction(op.cellValue)) {
  20075. //add this one even if cellval is blank string
  20076. return "<a " + target + " href='" + encodeAttr(idUrl) + "'>" +
  20077. ($.isFunction(op.cellValue) ? getOptionValue(op.cellValue) : cellval) +
  20078. "</a>";
  20079. }
  20080. // the code below will be called typically for undefined cellval or
  20081. // if cellval have null value or some other unclear value like an object
  20082. // and no cellValue callback function are defined "to decode" the value
  20083. return defaultFormat(cellval, op);
  20084. };
  20085. };
  20086. $FnFmatter.showlink.pageFinalization = function (iCol) {
  20087. var $self = $(this), p = this.p, cm = p.colModel[iCol],
  20088. wrapperClassName = p.autoResizing.wrapperClassName,
  20089. iRow, rows = this.rows, nRows = rows.length, row, td,
  20090. onClick = function (e) {
  20091. var $td = $(this).closest("tr.jqgrow>td"), $tr = $td.parent(), iCol = $td[0].cellIndex, cm = p.colModel[iCol];
  20092. if ($tr.length > 0) {
  20093. return cm.formatoptions.onClick.call($self[0], {
  20094. iCol: iCol,
  20095. iRow: $tr[0].rowIndex,
  20096. rowid: $tr.attr("id"),
  20097. cm: cm,
  20098. cmName: cm.name,
  20099. cellValue: $(this).text(),
  20100. a: this,
  20101. event: e
  20102. });
  20103. }
  20104. };
  20105. if (cm.formatoptions != null && $.isFunction(cm.formatoptions.onClick)) {
  20106. for (iRow = 0; iRow < nRows; iRow++) {
  20107. row = rows[iRow];
  20108. if ($(row).hasClass("jqgrow")) {
  20109. td = row.cells[iCol];
  20110. if (cm.autoResizable && td != null && $(td.firstChild).hasClass(wrapperClassName)) {
  20111. td = td.firstChild;
  20112. }
  20113. if (td != null) {
  20114. $(td.firstChild).on("click", onClick);
  20115. }
  20116. }
  20117. }
  20118. }
  20119. };
  20120. var insertPrefixAndSuffix = function (sOutput, opts) {
  20121. // Prepend prefix
  20122. sOutput = (opts.prefix) ? opts.prefix + sOutput : sOutput;
  20123. // Append suffix
  20124. return (opts.suffix) ? sOutput + opts.suffix : sOutput;
  20125. },
  20126. numberHelper = function (cellval, opts, formatType) {
  20127. var colModel = opts.colModel, op = $.extend({}, opts[formatType]);
  20128. if (colModel != null) {
  20129. op = $.extend({}, op, colModel.formatoptions || {});
  20130. }
  20131. if (fmatter.isEmpty(cellval)) {
  20132. return insertPrefixAndSuffix(op.defaultValue, op);
  20133. }
  20134. return insertPrefixAndSuffix(fmatter.NumberFormat(cellval, op), op);
  20135. };
  20136. $FnFmatter.integer = function (cellval, opts) {
  20137. return numberHelper(cellval, opts, "integer");
  20138. };
  20139. $FnFmatter.number = function (cellval, opts) {
  20140. return numberHelper(cellval, opts, "number");
  20141. };
  20142. $FnFmatter.currency = function (cellval, opts) {
  20143. return numberHelper(cellval, opts, "currency");
  20144. };
  20145. var numberCellBuilder = function (opts, formatType) {
  20146. var colModel = opts.colModel, op = $.extend({}, opts[formatType]);
  20147. if (colModel != null) {
  20148. op = $.extend({}, op, colModel.formatoptions || {});
  20149. }
  20150. var numberFormat = fmatter.NumberFormat,
  20151. defaultValue = op.defaultValue ? insertPrefixAndSuffix(op.defaultValue, op) : "";
  20152. return function (cellValue) {
  20153. if (fmatter.isEmpty(cellValue)) { return defaultValue; }
  20154. return insertPrefixAndSuffix(numberFormat(cellValue, op), op);
  20155. };
  20156. };
  20157. $FnFmatter.integer.getCellBuilder = function (options) {
  20158. return numberCellBuilder(options, "integer");
  20159. };
  20160. $FnFmatter.number.getCellBuilder = function (options) {
  20161. return numberCellBuilder(options, "number");
  20162. };
  20163. $FnFmatter.currency.getCellBuilder = function (options) {
  20164. return numberCellBuilder(options, "currency");
  20165. };
  20166. $FnFmatter.date = function (cellval, opts, rwd, act) {
  20167. var colModel = opts.colModel, op = $.extend({}, opts.date);
  20168. if (colModel != null) {
  20169. op = $.extend({}, op, colModel.formatoptions || {});
  20170. }
  20171. if (!op.reformatAfterEdit && act === "edit") {
  20172. return defaultFormat(cellval, op);
  20173. }
  20174. if (!fmatter.isEmpty(cellval)) {
  20175. return jgrid.parseDate.call(this, op.srcformat, cellval, op.newformat, op);
  20176. }
  20177. return defaultFormat(cellval, op);
  20178. };
  20179. $FnFmatter.date.getCellBuilder = function (opts, act) {
  20180. var op = $.extend({}, opts.date);
  20181. if (opts.colModel != null) {
  20182. op = $.extend({}, op, opts.colModel.formatoptions || {});
  20183. }
  20184. var parseDate = jgrid.parseDate,
  20185. srcformat = op.srcformat, newformat = op.newformat;
  20186. if (!op.reformatAfterEdit && act === "edit") {
  20187. return function (cellValue) {
  20188. return defaultFormat(cellValue, op);
  20189. };
  20190. }
  20191. return function (cellValue) {
  20192. return fmatter.isEmpty(cellValue) ?
  20193. defaultFormat(cellValue, op) :
  20194. parseDate.call(this, srcformat, cellValue, newformat, op);
  20195. };
  20196. };
  20197. $FnFmatter.select = function (cellval, opts) {
  20198. var ret = [], colModel = opts.colModel, defaultValue,
  20199. op = $.extend({}, colModel.editoptions || {}, colModel.formatoptions || {}),
  20200. oSelect = typeof op.value === "function" ? op.value() : op.value, sep = op.separator || ":", delim = op.delimiter || ";";
  20201. if (oSelect) {
  20202. var msl = op.multiple === true ? true : false, scell = [], sv,
  20203. mapFunc = function (n, j) { if (j > 0) { return n; } };
  20204. if (msl) {
  20205. scell = $.map(String(cellval).split(","), function (n) { return $.trim(n); });
  20206. }
  20207. if (typeof oSelect === "string") {
  20208. // maybe here we can use some caching with care ????
  20209. var so = oSelect.split(delim), i, v;
  20210. for (i = 0; i < so.length; i++) {
  20211. sv = so[i].split(sep);
  20212. if (sv.length > 2) {
  20213. sv[1] = $.map(sv, mapFunc).join(sep);
  20214. }
  20215. v = $.trim(sv[0]);
  20216. if (op.defaultValue === v) {
  20217. defaultValue = sv[1];
  20218. }
  20219. if (msl) {
  20220. if ($.inArray(v, scell) > -1) {
  20221. ret.push(sv[1]);
  20222. }
  20223. } else if (v === $.trim(cellval)) {
  20224. ret = [sv[1]];
  20225. break;
  20226. }
  20227. }
  20228. } else if (fmatter.isObject(oSelect)) {
  20229. defaultValue = oSelect[op.defaultValue];
  20230. if (msl) {
  20231. ret = $.map(scell, function (n) {
  20232. return oSelect[n];
  20233. });
  20234. } else {
  20235. ret = [oSelect[cellval] === undefined ? "" : oSelect[cellval]];
  20236. }
  20237. }
  20238. }
  20239. cellval = ret.join(", ");
  20240. return cellval !== "" ? cellval :
  20241. (op.defaultValue !== undefined ? defaultValue : defaultFormat(cellval, op));
  20242. };
  20243. $FnFmatter.select.getCellBuilder = function (opts) {
  20244. // jqGrid specific
  20245. var colModel = opts.colModel, $fnDefaultFormat = $FnFmatter.defaultFormat,
  20246. op = $.extend({}, colModel.editoptions || {}, colModel.formatoptions || {}),
  20247. oSelect = typeof op.value === "function" ? op.value() : op.value, sep = op.separator || ":", delim = op.delimiter || ";",
  20248. defaultValue, defaultValueDefined = op.defaultValue !== undefined,
  20249. isMultiple = op.multiple === true ? true : false, sv, so, i, nOpts, selOptions = {},
  20250. mapFunc = function (n, j) { if (j > 0) { return n; } };
  20251. if (typeof oSelect === "string") {
  20252. // maybe here we can use some caching with care ????
  20253. so = oSelect.split(delim);
  20254. nOpts = so.length;
  20255. for (i = nOpts - 1; i >= 0; i--) {
  20256. sv = so[i].split(sep);
  20257. if (sv.length > 2) {
  20258. sv[1] = $.map(sv, mapFunc).join(sep);
  20259. }
  20260. selOptions[$.trim(sv[0])] = sv[1];
  20261. }
  20262. } else if (fmatter.isObject(oSelect)) {
  20263. selOptions = oSelect;
  20264. } else {
  20265. return function (cellValue) {
  20266. return cellValue ? String(cellValue) : $fnDefaultFormat(cellValue, op);
  20267. };
  20268. }
  20269. if (defaultValueDefined) {
  20270. defaultValue = selOptions[op.defaultValue];
  20271. }
  20272. return isMultiple ?
  20273. function (cellValue) {
  20274. var ret = [], iOpt,
  20275. splitedCell = $.map(String(cellValue).split(","), function (n) { return $.trim(n); });
  20276. for (iOpt = 0; iOpt < splitedCell.length; iOpt++) {
  20277. cellValue = splitedCell[iOpt];
  20278. if (selOptions.hasOwnProperty(cellValue)) {
  20279. ret.push(selOptions[cellValue]);
  20280. }
  20281. }
  20282. cellValue = ret.join(", ");
  20283. return cellValue !== "" ? cellValue :
  20284. (defaultValueDefined ? defaultValue : $fnDefaultFormat(cellValue, op));
  20285. } :
  20286. function (cellValue) {
  20287. var ret = selOptions[String(cellValue)];
  20288. return ret !== "" && ret !== undefined ? ret :
  20289. (defaultValueDefined ? defaultValue : $fnDefaultFormat(cellValue, op));
  20290. };
  20291. };
  20292. $FnFmatter.rowactions = function (e, act) {
  20293. var $td = $(this).closest("tr.jqgrow>td"), $tr = $td.parent(), rid = $tr.attr("id"),
  20294. $id = $(this).closest("table.ui-jqgrid-btable").attr("id").replace(/_frozen([^_]*)$/, "$1"),
  20295. $grid = $("#" + jgrid.jqID($id)), $t = $grid[0], p = $t.p, i, n, customAction, actop,
  20296. relativeTop = jgrid.getRelativeRect.call($t, $tr).top,
  20297. cm = p.colModel[$td[0].cellIndex],
  20298. op = $.extend(true, { extraparam: {} }, jgrid.actionsNav || {}, p.actionsNavOptions || {}, cm.formatoptions || {});
  20299. if (p.editOptions !== undefined) {
  20300. op.editOptions = $.extend(true, op.editOptions || {}, p.editOptions);
  20301. }
  20302. if (p.delOptions !== undefined) {
  20303. op.delOptions = p.delOptions;
  20304. }
  20305. if ($tr.hasClass("jqgrid-new-row")) {
  20306. op.extraparam[p.prmNames.oper] = p.prmNames.addoper;
  20307. }
  20308. actop = {
  20309. keys: op.keys,
  20310. oneditfunc: op.onEdit,
  20311. successfunc: op.onSuccess,
  20312. url: op.url,
  20313. extraparam: op.extraparam,
  20314. aftersavefunc: op.afterSave,
  20315. errorfunc: op.onError,
  20316. afterrestorefunc: op.afterRestore,
  20317. restoreAfterError: op.restoreAfterError,
  20318. mtype: op.mtype
  20319. };
  20320. if ((!p.multiselect && rid !== p.selrow) || (p.multiselect && $.inArray(rid, p.selarrrow) < 0)) {
  20321. $grid.jqGrid("setSelection", rid, true, e);
  20322. } else {
  20323. jgrid.fullBoolFeedback.call($t, "onSelectRow", "jqGridSelectRow", rid, true, e);
  20324. }
  20325. switch (act) {
  20326. case "edit":
  20327. $grid.jqGrid("editRow", rid, actop);
  20328. break;
  20329. case "save":
  20330. $grid.jqGrid("saveRow", rid, actop);
  20331. break;
  20332. case "cancel":
  20333. $grid.jqGrid("restoreRow", rid, op.afterRestore);
  20334. break;
  20335. case "del":
  20336. op.delOptions = op.delOptions || {};
  20337. if (op.delOptions.top === undefined) {
  20338. op.delOptions.top = relativeTop;
  20339. }
  20340. $grid.jqGrid("delGridRow", rid, op.delOptions);
  20341. break;
  20342. case "formedit":
  20343. op.editOptions = op.editOptions || {};
  20344. if (op.editOptions.top === undefined) {
  20345. op.editOptions.top = relativeTop;
  20346. op.editOptions.recreateForm = true;
  20347. }
  20348. $grid.jqGrid("editGridRow", rid, op.editOptions);
  20349. break;
  20350. default:
  20351. if (op.custom != null && op.custom.length > 0) {
  20352. n = op.custom.length;
  20353. for (i = 0; i < n; i++) {
  20354. customAction = op.custom[i];
  20355. if (customAction.action === act && $.isFunction(customAction.onClick)) {
  20356. customAction.onClick.call($t, { rowid: rid, event: e, action: act, options: customAction });
  20357. }
  20358. }
  20359. }
  20360. }
  20361. if (e.stopPropagation) {
  20362. e.stopPropagation();
  20363. }
  20364. return false; // prevent other processing of the click on the row
  20365. };
  20366. $FnFmatter.actions = function (cellval, opts, rwd, act) {
  20367. var rowid = opts.rowId, str = "", $t = this, $self = $($t), i, info, customAction, displayMask = {},
  20368. edit = getGridRes.call($self, "edit") || {},
  20369. op = $.extend({
  20370. editbutton: true,
  20371. delbutton: true,
  20372. editformbutton: false,
  20373. commonIconClass: "ui-icon",
  20374. editicon: "ui-icon-pencil",
  20375. delicon: "ui-icon-trash",
  20376. saveicon: "ui-icon-disk",
  20377. cancelicon: "ui-icon-cancel",
  20378. savetitle: edit.bSubmit || "",
  20379. canceltitle: edit.bCancel || ""
  20380. },
  20381. getGridRes.call($self, "nav") || {},
  20382. jgrid.nav || {},
  20383. $t.p.navOptions || {},
  20384. getGridRes.call($self, "actionsNav") || {},
  20385. jgrid.actionsNav || {},
  20386. $t.p.actionsNavOptions || {},
  20387. (opts.colModel || {}).formatoptions || {}),
  20388. cssIconClass = function (name) {
  20389. return jgrid.mergeCssClasses(op.commonIconClass, op[name + "icon"]);
  20390. },
  20391. buttonInfos = [
  20392. { action: "edit", actionName: "formedit", display: op.editformbutton },
  20393. { action: "edit", display: !op.editformbutton && op.editbutton },
  20394. { action: "del", idPrefix: "Delete", display: op.delbutton },
  20395. { action: "save", display: op.editformbutton || op.editbutton, hidden: true },
  20396. { action: "cancel", display: op.editformbutton || op.editbutton, hidden: true }
  20397. ],
  20398. actionButton = function (options) {
  20399. var action = options.action, actionName = options.actionName || action,
  20400. idPrefix = options.idPrefix !== undefined ? options.idPrefix : (action.charAt(0).toUpperCase() + action.substring(1));
  20401. return "<div title='" + encodeAttr(op[action + "title"]) +
  20402. (options.hidden ? "' style='display:none;" : "") +
  20403. "' class='" + encodeAttr($self.jqGrid("getGuiStyles", "actionsButton", "ui-pg-div ui-inline-" + action)) + "' " +
  20404. (idPrefix !== null ? "id='j" + encodeAttr(idPrefix + "Button_" + rowid) : "") +
  20405. "' data-jqactionname=\"" + actionName + "\" " +
  20406. (options.noHovering ? "" : "' data-jqhovering=\"1\" ") +
  20407. "><span class='" +
  20408. encodeAttr(cssIconClass(action)) + "'></span></div>";
  20409. },
  20410. n = op.custom != null ? op.custom.length - 1 : -1;
  20411. if (rowid === undefined || fmatter.isEmpty(rowid)) { return ""; }
  20412. if ($.isFunction(op.isDisplayButtons)) {
  20413. try {
  20414. displayMask = op.isDisplayButtons.call(this, op, rwd, act) || {};
  20415. } catch (ignore) {}
  20416. }
  20417. while (n >= 0) {
  20418. customAction = op.custom[n--];
  20419. buttonInfos[customAction.position === "first" ? "unshift" : "push"](customAction);
  20420. }
  20421. for (i = 0, n = buttonInfos.length; i < n; i++) {
  20422. info = $.extend({}, buttonInfos[i], displayMask[buttonInfos[i].action] || {});
  20423. if (info.display !== false) {
  20424. str += actionButton(info);
  20425. }
  20426. }
  20427. return "<div class='" + encodeAttr($self.jqGrid("getGuiStyles", "actionsDiv", "ui-jqgrid-actions")) + "'>" + str + "</div>";
  20428. };
  20429. $FnFmatter.actions.pageFinalization = function (iCol) {
  20430. var $self = $(this), p = this.p, cm = p.colModel[iCol],
  20431. wrapperClassName = p.autoResizing.wrapperClassName,
  20432. hoverClass = $self.jqGrid("getGuiStyles", "states.hover"),
  20433. iRow, rows = this.rows, fbRows = this.grid.fbRows, nRows = rows.length, row,
  20434. showHideEditDelete = (function (cmName) {
  20435. return function (show, tr) {
  20436. var maxfrozen = 0, $actionsDiv, colModel = p.colModel, len = colModel.length, i, iCol = p.iColByName[cmName];
  20437. for (i = 0; i < len; i++) {
  20438. // from left, no breaking frozen
  20439. if (colModel[i].frozen !== true) {
  20440. break;
  20441. }
  20442. maxfrozen = i;
  20443. }
  20444. if (tr != null && tr.cells != null) {
  20445. $actionsDiv = $(tr.cells[iCol]).children(".ui-jqgrid-actions");
  20446. if (colModel[iCol].frozen && p.frozenColumns && iCol <= maxfrozen) {
  20447. // uses the corresponding tr from frozen div with the same rowIndex ADDITIONALLY
  20448. // to the standard action div
  20449. $actionsDiv = $actionsDiv
  20450. .add($($self[0].grid.fbRows[tr.rowIndex].cells[iCol])
  20451. .children(".ui-jqgrid-actions"));
  20452. }
  20453. if (show) {
  20454. $actionsDiv.find(">.ui-inline-edit,>.ui-inline-del").show();
  20455. $actionsDiv.find(">.ui-inline-save,>.ui-inline-cancel").hide();
  20456. } else {
  20457. $actionsDiv.find(">.ui-inline-edit,>.ui-inline-del").hide();
  20458. $actionsDiv.find(">.ui-inline-save,>.ui-inline-cancel").show();
  20459. }
  20460. }
  20461. };
  20462. })(cm.name),
  20463. showEditDelete = function (e, rowid) {
  20464. var tr = $self.jqGrid("getGridRowById", rowid);
  20465. showHideEditDelete(true, tr);
  20466. return false;
  20467. },
  20468. hideEditDelete = function (e, rowid) {
  20469. var tr = $self.jqGrid("getGridRowById", rowid);
  20470. showHideEditDelete(false, tr);
  20471. return false;
  20472. },
  20473. onMouseOver = function (e) {
  20474. if ($(e.target).closest("div.ui-pg-div").data("jqhovering") === 1) {
  20475. $(this).addClass(hoverClass);
  20476. }
  20477. },
  20478. onMouseOut = function (e) {
  20479. if ($(e.target).closest("div.ui-pg-div").data("jqhovering") === 1) {
  20480. $(this).removeClass(hoverClass);
  20481. }
  20482. },
  20483. onClick = function (e) {
  20484. return $FnFmatter.rowactions.call(this, e, $(e.target).closest("div.ui-pg-div").data("jqactionname"));
  20485. },
  20486. bindEvents = function (td, autoResizable) {
  20487. if (autoResizable && td != null && $(td.firstChild).hasClass(wrapperClassName)) {
  20488. td = td.firstChild;
  20489. }
  20490. if (td != null) {
  20491. $(td.firstChild).on("click", onClick);
  20492. $(td.firstChild).children("div.ui-pg-div")
  20493. .on("mouseover", onMouseOver)
  20494. .on("mouseout", onMouseOut);
  20495. }
  20496. },
  20497. bindRowEvents = (function (cmName) {
  20498. return function (e, options) {
  20499. var iColToBind = p.iColByName[cmName]; // it could be changed index because of reordering of columns
  20500. bindEvents(options.tr.cells[iColToBind], p.colModel[iColToBind].autoResizable);
  20501. };
  20502. })(cm.name);
  20503. if (cm.formatoptions == null || !cm.formatoptions.editformbutton) {
  20504. // we use unbind to be sure that we don't register the same events multiple times
  20505. $self.off("jqGridInlineAfterRestoreRow.jqGridFormatter jqGridInlineAfterSaveRow.jqGridFormatter", showEditDelete);
  20506. $self.on("jqGridInlineAfterRestoreRow.jqGridFormatter jqGridInlineAfterSaveRow.jqGridFormatter", showEditDelete);
  20507. $self.off("jqGridInlineEditRow.jqGridFormatter", hideEditDelete);
  20508. $self.on("jqGridInlineEditRow.jqGridFormatter", hideEditDelete);
  20509. $self.off("jqGridAfterAddRow.jqGridFormatter", bindRowEvents);
  20510. $self.on("jqGridAfterAddRow.jqGridFormatter", bindRowEvents);
  20511. }
  20512. for (iRow = 0; iRow < nRows; iRow++) {
  20513. row = rows[iRow];
  20514. if ($(row).hasClass("jqgrow")) {
  20515. bindEvents(row.cells[iCol], cm.autoResizable);
  20516. if (fbRows != null && fbRows[iRow] != null) {
  20517. bindEvents(fbRows[iRow].cells[iCol], cm.autoResizable);
  20518. }
  20519. }
  20520. }
  20521. };
  20522. $.unformat = function (cellval, options, pos, cnt) {
  20523. // specific for jqGrid only
  20524. var ret, colModel = options.colModel, formatType = colModel.formatter, p = this.p,
  20525. op = colModel.formatoptions || {},// sep,
  20526. //re = /([\.\*\_\'\(\)\{\}\+\?\\])/g,
  20527. unformatFunc = colModel.unformat || ($FnFmatter[formatType] && $FnFmatter[formatType].unformat);
  20528. if (cellval instanceof jQuery && cellval.length > 0) {
  20529. cellval = cellval[0];
  20530. }
  20531. if (p.treeGrid && cellval != null && $(cellval.firstChild).hasClass("tree-wrap") && ($(cellval.lastChild).hasClass("cell-wrapper") || $(cellval.lastChild).hasClass("cell-wrapperleaf"))) {
  20532. cellval = cellval.lastChild;
  20533. }
  20534. if (colModel.autoResizable && cellval != null && $(cellval.firstChild).hasClass(p.autoResizing.wrapperClassName)) {
  20535. cellval = cellval.firstChild;
  20536. }
  20537. if (unformatFunc !== undefined && $.isFunction(unformatFunc)) {
  20538. ret = unformatFunc.call(this, $(cellval).text(), options, cellval);
  20539. } else if (formatType !== undefined && typeof formatType === "string") {
  20540. //var opts = $.extend(true, {}, getRes(locales[p.locale], "formatter"), jgrid.formatter || {}), stripTag;
  20541. var $self = $(this), //stripTag, //opts = getGridRes.call($self, "formatter"),
  20542. getFormaterOption = function (formatterName, optionName) {
  20543. return op[optionName] !== undefined ?
  20544. op[optionName] :
  20545. getGridRes.call($self, "formatter." + formatterName + "." + optionName);
  20546. },
  20547. cutThousandsSeparator = function (formatterName, val) {
  20548. var separator = getFormaterOption(formatterName, "thousandsSeparator")
  20549. .replace(/([\.\*\_\'\(\)\{\}\+\?\\])/g, "\\$1");
  20550. return val.replace(new RegExp(separator, "g"), "");
  20551. };
  20552. switch (formatType) {
  20553. case "integer":
  20554. ret = cutThousandsSeparator("integer", $(cellval).text());
  20555. break;
  20556. case "number":
  20557. ret = cutThousandsSeparator("number", $(cellval).text())
  20558. .replace(getFormaterOption("number", "decimalSeparator"), ".");
  20559. break;
  20560. case "currency":
  20561. ret = $(cellval).text();
  20562. var prefix = getFormaterOption("currency", "prefix"),
  20563. suffix = getFormaterOption("currency", "suffix");
  20564. if (prefix && prefix.length) {
  20565. ret = ret.substr(prefix.length);
  20566. }
  20567. if (suffix && suffix.length) {
  20568. ret = ret.substr(0, ret.length - suffix.length);
  20569. }
  20570. ret = cutThousandsSeparator("number", ret)
  20571. .replace(getFormaterOption("number", "decimalSeparator"), ".");
  20572. break;
  20573. case "checkbox":
  20574. ret = $FnFmatter.checkbox.unformat(cellval, options, cellval);
  20575. break;
  20576. case "select":
  20577. ret = $.unformat.select(cellval, options, pos, cnt);
  20578. break;
  20579. case "actions":
  20580. return "";
  20581. default:
  20582. ret = $(cellval).text();
  20583. }
  20584. }
  20585. ret = ret !== undefined ? ret : cnt === true ? $(cellval).text() : jgrid.htmlDecode($(cellval).html());
  20586. return ret;
  20587. };
  20588. $.unformat.select = function (cellval, options, pos, cnt) {
  20589. // Spacial case when we have local data and perform a sort
  20590. // cnt is set to true only in sortDataArray
  20591. var ret = [], cell = $(cellval).text(), colModel = options.colModel;
  20592. if (cnt === true) { return cell; }
  20593. var op = $.extend({}, colModel.editoptions || {}, colModel.formatoptions || {}),
  20594. sep = op.separator === undefined ? ":" : op.separator,
  20595. delim = op.delimiter === undefined ? ";" : op.delimiter;
  20596. if (op.value) {
  20597. var oSelect = typeof op.value === "function" ? op.value() : op.value,
  20598. msl = op.multiple === true ? true : false,
  20599. scell = [], sv, mapFunc = function (n, k) { if (k > 0) { return n; } };
  20600. if (msl) { scell = cell.split(","); scell = $.map(scell, function (n) { return $.trim(n); }); }
  20601. if (typeof oSelect === "string") {
  20602. var so = oSelect.split(delim), j = 0, i;
  20603. for (i = 0; i < so.length; i++) {
  20604. sv = so[i].split(sep);
  20605. if (sv.length > 2) {
  20606. sv[1] = $.map(sv, mapFunc).join(sep);
  20607. }
  20608. if (msl) {
  20609. if ($.inArray($.trim(sv[1]), scell) > -1) {
  20610. ret[j] = sv[0];
  20611. j++;
  20612. }
  20613. } else if ($.trim(sv[1]) === $.trim(cell)) {
  20614. ret[0] = sv[0];
  20615. break;
  20616. }
  20617. }
  20618. } else if (fmatter.isObject(oSelect) || $.isArray(oSelect)) {
  20619. if (!msl) { scell[0] = cell; }
  20620. ret = $.map(scell, function (n) {
  20621. var rv;
  20622. $.each(oSelect, function (k, val) {
  20623. if (val === n) {
  20624. rv = k;
  20625. return false;
  20626. }
  20627. });
  20628. if (rv !== undefined) { return rv; }
  20629. });
  20630. }
  20631. return ret.join(", ");
  20632. }
  20633. return cell || "";
  20634. };
  20635. $.unformat.date = function (cellval, opts) {
  20636. // TODO
  20637. var op = $.extend(true, {},
  20638. getGridRes.call($(this), "formatter.date"),
  20639. jgrid.formatter.date || {},
  20640. opts.formatoptions || {});
  20641. return !fmatter.isEmpty(cellval) ?
  20642. jgrid.parseDate.call(this, op.newformat, cellval, op.srcformat, op) :
  20643. "";
  20644. };
  20645. // end module jquery.fmatter
  20646. }));