ÿØÿà JFIF    ÿÛ „  ( %"1!%)+...383,7(-.+  -+++--++++---+-+-----+---------------+---+-++7-----ÿÀ  ß â" ÿÄ     ÿÄ H    !1AQaq"‘¡2B±ÁÑð#R“Ò Tbr‚²á3csƒ’ÂñDS¢³$CÿÄ   ÿÄ %  !1AQa"23‘ÿÚ   ? ôÿ ¨pŸªáÿ —åYõõ\?àÒü©ŠÄï¨pŸªáÿ —åYõõ\?àÓü©ŠÄá 0Ÿªáÿ Ÿå[úƒ ú®ði~TÁbqÐ8OÕpÿ ƒOò¤Oè`–RÂáœá™êi€ßÉ< FtŸI“öÌ8úDf´°å}“¾œ6  öFá°y¥jñÇh†ˆ¢ã/ÃÐ:ªcÈ "Y¡ðÑl>ÿ ”ÏËte:qž\oäŠe÷󲍷˜HT4&ÿ ÓÐü6ö®¿øþßèô Ÿ•7Ñi’•j|“ñì>b…þS?*Óôÿ ÓÐü*h¥£ír¶ü UãS炟[AÐaè[ûª•õ&õj?†Éö+EzP—WeÒírJFt ‘BŒ†Ï‡%#tE Øz ¥OÛ«!1›üä±Í™%ºÍãö]°î(–:@<‹ŒÊö×òÆt¦ãº+‡¦%ÌÁ²h´OƒJŒtMÜ>ÀÜÊw3Y´•牋4ǍýʏTì>œú=Íwhyë,¾Ôò×õ¿ßÊa»«þˆѪQ|%6ž™A õ%:øj<>É—ÿ Å_ˆCbõ¥š±ý¯Ýƒï…¶|RëócÍf溪“t.СøTÿ *Ä¿-{†çàczůŽ_–^XþŒ±miB[X±d 1,é”zEù»& î9gœf™9Ð'.;—™i}!ôšåîqêÛ٤ёý£½ÆA–àôe"A$˝Úsäÿ ÷Û #°xŸëí(l »ý3—¥5m! rt`†0~'j2(]S¦¦kv,ÚÇ l¦øJA£Šƒ J3E8ÙiŽ:cÉžúeZ°€¯\®kÖ(79«Ž:¯X”¾³Š&¡* ….‰Ž(ÜíŸ2¥ª‡×Hi²TF¤ò[¨íÈRëÉ䢍mgÑ.Ÿ<öäS0í„ǹÁU´f#Vß;Õ–…P@3ío<ä-±»Ž.L|kªÀê›fÂ6@»eu‚|ÓaÞÆŸ…¨ááå>åŠ?cKü6ùTÍÆ”†sĤÚ;H2RÚ†õ\Ö·Ÿn'¾ ñ#ºI¤Å´%çÁ­‚â7›‹qT3Iï¨ÖÚ5I7Ë!ÅOóŸ¶øÝñØôת¦$Tcö‘[«Ö³šÒ';Aþ ¸èíg A2Z"i¸vdÄ÷.iõ®§)¿]¤À†–‡É&ä{V¶iŽ”.Ó×Õÿ û?h¬Mt–íª[ÿ Ñÿ ÌV(í}=ibÔ¡›¥¢±b Lô¥‡piη_Z<‡z§èŒ)iÖwiÇ 2hÙ3·=’d÷8éŽ1¦¸c¤µ€7›7Ø ð\á)} ¹fËí›pAÃL%âc2 í§æQz¿;T8sæ°qø)QFMð‰XŒÂ±N¢aF¨…8¯!U  Z©RÊ ÖPVÄÀÍin™Ì-GˆªÅËŠ›•zË}º±ŽÍFò¹}Uw×#ä5B¤{î}Ð<ÙD é©¤&‡ïDbàÁôMÁ." ¤‡ú*õ'VŽ|¼´Úgllº¼klz[Æüï÷Aób‡Eÿ dÑ»Xx9ÃÜ£ÁT/`¼¸vI±Ýµ·Ë‚“G³þ*Ÿû´r|*}<¨îºœ @¦mÄ’M¹”.œ«Y–|6ÏU¤jç¥ÕÞqO ˜kDÆÁ¨5ÿ š;ÐЦ¦€GÙk \ –Þ=â¼=SͧµªS°ÚÍpÜãQűÀõ¬?ÃÁ1Ñ•õZà?hóœ€ L¦l{Y*K˜Ù›zc˜–ˆâ ø+¾ ­-Ök¥%ùEÜA'}ˆ><ÊIè“bpÍ/qÞâvoX€w,\úªò6Z[XdÒæ­@Ö—€$òJí#é>'°Ú ôª˜<)4ryÙ£|óAÅn5žêŸyÒäMÝ2{"}‰–¤l÷ûWX\l¾Á¸góÉOÔ /óñB¤f¸çñ[.P˜ZsÊË*ßT܈§QN¢’¡¨§V¼(Üù*eÕ“”5T¨‹Âê¥FŒã½Dü[8'Ò¥a…Ú¶k7a *•›¼'Ò·\8¨ª\@\õ¢¦íq+DÙrmÎ…_ªæ»ŠÓœ¡¯’Ré9MÅ×D™lælffc+ŒÑ,ý™ÿ ¯þǤ=Å’Á7µ÷ÚÛ/“Ü€ñýã¼àí¾ÕÑ+ƒ,uµMâÀÄbm:ÒÎPæ{˜Gz[ƒ¯«® KHà`ߨŠéí¯P8Aq.C‰ à€kòpj´kN¶qô€…Õ,ÜNŠª-­{Zö’æû44‰sŽè‰îVíRœÕm" 6?³D9¡ÇTíÅꋇ`4«¸ÝÁô ï’ýorqКÇZ«x4Žâéþuïf¹µö[P ,Q£éaX±`PÉÍZ ¸äYúg üAx ’6Lê‚xÝÓ*äQ  Ï’¨hÍ =²,6ï#rÃ<¯–£»ƒ‹,–ê•€ aÛsñ'%Æ"®ÛüìBᝠHÚ3ß°©$“XnœÖ’î2ËTeûìxîß ¦å¿çÉ ðK§þ{‘t‚Ϋ¬jéîZ[ ”š7L¥4VÚCE×]m¤Øy”ä4-dz£œ§¸x.*ãÊÊ b÷•h:©‡¦s`BTÁRû¾g⻩‹jø sF¢àJøFl‘È•Xᓁà~*j¯ +(ÚÕ6-£¯÷GŠØy‚<Ç’.F‹Hœw(+)ÜÜâÈzÄäT§FߘãÏ;DmVœ3Àu@mÚüXÝü•3B¨òÌÁÛ<·ÃÜ z,Ì@õÅ·d2]ü8s÷IôÞ¯^Ç9¢u„~ëAŸï4«M? K]­ÅàPl@s_ p:°¬ZR”´›JC[CS.h‹ƒïËœ«Æ]–÷ó‚wR×k7X‰k›‘´ù¦=¡«‰¨¨Â')—71ó’c‡Ðúµ `é.{§p¹ój\Ž{1h{o±Ý=áUÊïGÖŒõ–-BÄm+AZX¶¡ ïHðæ¥JmÙ;…䡟ˆ¦ ° äšiÉg«$üMk5¤L“’çÊvïâï ,=f“"íἊ5ô¬x6{ɏžID0e¸vçmi'︧ºð9$ò¹÷*£’9ÿ ²TÔ…×>JV¥}Œ}$p[bÔ®*[jzS*8 ”·T›Í–ñUîƒwo$áè=LT™ç—~ô·¤ÈÚ$榍q‰„+´kFm)ž‹©i–ËqÞŠ‰à¶ü( ‚•§ •°ò·‡#5ª•µÊ﯅¡X¨šÁ*F#TXJÊ ušJVÍ&=iÄs1‚3•'fý§5Ñ<=[íÞ­ PÚ;ѱÌ_~Ä££8rÞ ²w;’hDT°>ÈG¬8Á²ÚzŽ®ò®qZcqJêäÞ-ö[ܘbň±çb“ж31²n×iƒðÕ;1¶þÉ ªX‰,ßqÏ$>•î íZ¥Z 1{ç൵+ƒÕµ¥°T$§K]á»Ûï*·¤tMI’ÂZbŽÕiÒ˜}bÓ0£ª5›¨ [5Ž^ÝœWøÂÝh° ¢OWun£¤5 a2Z.G2³YL]jåtì”ä ÁÓ‘%"©<Ôúʰsº UZvä‡ÄiÆÒM .÷V·™ø#kèýiíÌ–ª)µT[)BˆõÑ xB¾B€ÖT¨.¥~ð@VĶr#¸ü*åZNDŽH;âi ],©£öØpù(šºãö¼T.uCê•4@ÿ GÕÛ)Cx›®0ø#:ÏðFÒbR\(€€Ä®fã4Þ‰Fä¯HXƒÅ,†öEÑÔÜ]Öv²?tLÃvBY£ú6Êu5ÅAQ³1‘’¬x–HŒÐ‡ ^ ¸KwJôÖŽ5×CÚ¨vÜ«/B0$×k°=ðbÇ(Ï)w±A†Á† 11Í=èQšµ626ŒÜ/`G«µ<}—-Ö7KEHÈÉðóȤmݱû±·ø«Snmá=“䫚mݱŸ¡¶~ó·“äUóJæúòB|E LêŽy´jDÔ$G¢þÐñ7óR8ýÒ…Ç› WVe#·Ÿ p·Fx~•ݤF÷0Èÿ K¯æS<6’¡WШ; ´ÿ ¥Êø\Òuî†åÝ–VNœkÒ7oòX¨Á­Ø÷FÎÑä±g÷ÿ M~Çî=p,X´ ÝÌÚÅ‹’ÃjÖ.ØöÏñ qïQ¤ÓZE†° =6·]܈ s¸>v•Ž^Ý\wq9r‰Î\¸¡kURÒ$­*‹Nq?Þª*!sŠÆ:TU_u±T+øX¡ ®¹¡,ÄâÃBTsÜ$Ø›4m椴zÜK]’’›Pƒ @€#â˜`é¹=I‡fiV•Ôî“nRm+µFPOhÍ0B£ €+¬5c v•:P'ÒyÎ ‰V~‚Ó†ÖuókDoh$å\*ö%Ю=£«…aȼ½÷Û.-½VŒŠ¼'lyî±1¬3ó#ÞE¿ÔS¤gV£m›=§\û"—WU¤ÚǼÿ ÂnÁGŒÃ ‚õN D³õNÚíŒÕ;HôyÄÈ©P¹Ä{:?R‘Ô¨âF÷ø£bÅó® JS|‚R÷ivýáâ€Æé¡è³´IئÑT!§˜•ت‚¬â@q€wnïCWÄ@JU€ê¯m6]Ï:£âx'+ÒðXvÓ¦Úm=–´7œ $ì“B£~p%ÕŸUþ« N@¼üï~w˜ñø5®—'Ôe»¤5ã//€ž~‰Tþ›Å7•#¤× Íö pÄ$ùeåì*«ÓŠEØWEÈsßg ¦ûvžSsLpºÊW–âµEWöˬH; ™!CYõZ ÃÄf æ#1W. \uWâ\,\Çf j’<qTbên›Î[vxx£ë 'ö¨1›˜ÀM¼Pÿ H)ƒêêŒA7s,|F“ 꺸k³9Ìö*ç®;Ö!Ö$Eiž•¹ÒÚ†ýóéÝû¾ÕS®ó$’NÝäŸz¤5r¦ãÄÃD÷Üø!°ø‡Ô&@m™Ì^Ãä­d q5Lnÿ N;.6½·N|#ä"1Nƒx“ã<3('&ñßt  ~ªu”1Tb㫨9ê–›–bìd$ߣ=#ÕãÒmU¯eí$EFù5ýYô櫨æì™Ç—±ssM]·á¿0ÕåJRÓªîiƒ+O58ÖñªŠÒx" \µâá¨i’¤i —Ö ” M+M¤ë9‚‰A¦°Qõ¾ßøK~¼Ã‘g…Ö´~÷Ï[3GUœÒ½#…kàÔ®Ò”‰³·dWV‰IP‰Ú8u¹”E ÖqLj¾êÕCBš{A^Âß;–¨`¯¬ìö ˼ ×tìø.tƐm*n¨y4o&Àx¥n¦×î‡aupáÛj8¿m›è¶ã!o½;ß0y^ý×^EÑ¿ÒjzŒ­)vÚÑnÄL …^ªô× ‡—‚3k Îý­hï]içå–îÏ*÷ñþ»Ô CÒjøjÍznˆ´ ¹#b'Fô‹ ‰v¥'’à'T´ƒHýÍ%M‰ ƒ&ÆÇŒï1 ‘ –Þ ‰i¬s žR-Ÿ kЬá¬7:þ 0ŒÅÒÕ/aÙ¬ÃÝ#Úøœ ©aiVc‰. ¹¦ãµ” ›Yg¦›ÆÎýº°f³7ƒhá·¸­}&D9¡ÂsÉÙÞèŠõØàC™¨ñbFC|´Ü(ŸƒÚÒ-%»'a Ì¿)ËÇn¿úÿ ÞŽX…4ÊÅH^ôΑí@ù¹Eh¶“L8Çjù ¼ÎåVªóR©Ï5uà V4lZß®=€xÖŸ–ÑÈ ÷”¨°¾__yM1tÉ?uÆþIkÄgæ@þ[¢†°XÃJ£j·:nkÅ¢u ‘}âGzö­/IµèЬ¼48q¦F°ŽR¼=ûì{´¯RýicS ÕÛ íNtÍÙï£,w4rêì®»~x(©Uñ§#Ñ&œÕ¤>ÎåÍÓ9’Ö{9eV­[Öjâ²ãu]˜å2›qÑšÕJç0€sÄ|Êëè0튔bÁ>“{×_F`Ø©ºê:µä,v¤ðfc1±"«ÔÍän1#=· Âøv~H½ÐßA¾¿Ü€Óš]Õ; I¾÷ç‚Qi†î¹9ywÔKG˜áñ zQY—§ÃÕZ07§X‚ Áh;ÁM)iÌCH-¯T‘ë|A0{Ò½LÚ–TâÖkÜ’dÀ“rmm»”جPF³ÖcbE§T€ÒxKºû’Ó®7±²(\4ŽÃ¸Uu@j™yĵ;³µ!Á¢b.W¤=mõ´êµK k ¸K^ÜÛ#p*Ü14qkZç5ïë †°5Ï%ÍÛ<Õ¤×Ô¥ê†C Õ´¼ú$ƒÖ“”]Ù¬qÞÚ[4©ý!ûÏ—Áb쳐XµA¬â~`›Çr¸8ìùÝ䫦<>ä÷«?xs´ÇÑ /á;¹øüÊÈÙà{"@Žïzâ¬[âß‚ U_<ÇŸ½4èN˜ú61®qŠu ¦þF£»äJ_ˆÙÎ~ ÞAã–݄ϗrŠD;xTž‘ô`É«…suãO`?³à™ô Lý#Íc5öoæØ‚y´´÷«ZR§<&JÇ+éâô´€i!Àˆ0æAoàðLèÖ-2ŸõW.’t^–(KÁmHµV@xÜÇy®Ñø­â^:Ú3w· 7½¹°ñ¸â¹®:',«Mœ—n­Á+Ãbš LÈ‘ÄnRÓÅœ%¦²‰¨ùQ:¤f‚ "PÕtô¸…cæl…&˜Ú˜Ôkv‹ž+vŠ,=¢v­6—Xy*¥t£«<™:“aîϲ=¦6rO]XI¿Œ÷¤zÚ­›¶ 6÷”w\d ü~v®ˆÌk«^m<ÿ ¢‰Õ\)ùºŽ;… lîÙÅEŠ®cѾ@vnMÏ,¼“ñ•ŽBxðÃzãÇç%3ˆ"}Ù•Åî> BÉú;Ò]V+P˜F_´ßé> Øše|ï‡ÄOmFæÇ ãqÞ$/xÐx­z`ï9"œÜij‚!7.\Td…9M‡•iŽ‹¾‘50ÞŽn¥ß4ÉôO ¹*í^QêËÜÇÌ8=ާs‰'ÂëÙ«á%Pú[O †ÅP¯Vsް.‰,kc¶ ¬A9n˜XÎ-ÞšN["¹QÕ‰ƒMýÁߺXJæÍaLj¾×Ãmã¾ãÚ uñÒþåQô¦¥ /ÄUx:‚ÍÜ’ Đ©ØÝ3V¨‰ÕnÐ6ó*óúK­«…c ¯U òhsý­jóÔj#,ímŒRµ«lbïUTŒÑ8†Ä0œÏr`ð¡¬É Ї ë"À² ™ 6¥ f¶ ¢ÚoܱԷ-<Àî)†a¶ž'Ú»¨TXqØæ¶÷YÄHy˜9ÈIW­YÀuMFë ºÏ’AqÌ4·/Ú †ô'i$øä­=Ä Ý|öK×40è|È6p‘0§)o¥ctî§H+CA-“ xØ|ÐXАç l8íºð3Ø:³¤¬KX¯UÿÙ /* vim: set expandtab sw=4 ts=4 sts=4: */ /** * @fileoverview function used in table data manipulation pages * * @requires jQuery * @requires jQueryUI * @requires js/functions.js * */ /** * Modify form controls when the "NULL" checkbox is checked * * @param theType string the MySQL field type * @param urlField string the urlencoded field name - OBSOLETE * @param md5Field string the md5 hashed field name * @param multi_edit string the multi_edit row sequence number * * @return boolean always true */ function nullify(theType, urlField, md5Field, multi_edit) { var rowForm = document.forms.insertForm; if (typeof(rowForm.elements['funcs' + multi_edit + '[' + md5Field + ']']) != 'undefined') { rowForm.elements['funcs' + multi_edit + '[' + md5Field + ']'].selectedIndex = -1; } // "ENUM" field with more than 20 characters if (theType == 1) { rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'][1].selectedIndex = -1; } // Other "ENUM" field else if (theType == 2) { var elts = rowForm.elements['fields' + multi_edit + '[' + md5Field + ']']; // when there is just one option in ENUM: if (elts.checked) { elts.checked = false; } else { var elts_cnt = elts.length; for (var i = 0; i < elts_cnt; i++) { elts[i].checked = false; } // end for } // end if } // "SET" field else if (theType == 3) { rowForm.elements['fields' + multi_edit + '[' + md5Field + '][]'].selectedIndex = -1; } // Foreign key field (drop-down) else if (theType == 4) { rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'].selectedIndex = -1; } // foreign key field (with browsing icon for foreign values) else if (theType == 6) { rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'].value = ''; } // Other field types else /*if (theType == 5)*/ { rowForm.elements['fields' + multi_edit + '[' + md5Field + ']'].value = ''; } // end if... else if... else return true; } // end of the 'nullify()' function /** * javascript DateTime format validation. * its used to prevent adding default (0000-00-00 00:00:00) to database when user enter wrong values * Start of validation part */ //function checks the number of days in febuary function daysInFebruary(year) { return (((year % 4 === 0) && (((year % 100 !== 0)) || (year % 400 === 0))) ? 29 : 28); } //function to convert single digit to double digit function fractionReplace(num) { num = parseInt(num, 10); return num >= 1 && num <= 9 ? '0' + num : '00'; } /* function to check the validity of date * The following patterns are accepted in this validation (accepted in mysql as well) * 1) 2001-12-23 * 2) 2001-1-2 * 3) 02-12-23 * 4) And instead of using '-' the following punctuations can be used (+,.,*,^,@,/) All these are accepted by mysql as well. Therefore no issues */ function isDate(val, tmstmp) { val = val.replace(/[.|*|^|+|//|@]/g, '-'); var arrayVal = val.split("-"); for (var a = 0; a < arrayVal.length; a++) { if (arrayVal[a].length == 1) { arrayVal[a] = fractionReplace(arrayVal[a]); } } val = arrayVal.join("-"); var pos = 2; var dtexp = new RegExp(/^([0-9]{4})-(((01|03|05|07|08|10|12)-((0[0-9])|([1-2][0-9])|(3[0-1])))|((02|04|06|09|11)-((0[0-9])|([1-2][0-9])|30))|((00)-(00)))$/); if (val.length == 8) { pos = 0; } if (dtexp.test(val)) { var month = parseInt(val.substring(pos + 3, pos + 5), 10); var day = parseInt(val.substring(pos + 6, pos + 8), 10); var year = parseInt(val.substring(0, pos + 2), 10); if (month == 2 && day > daysInFebruary(year)) { return false; } if (val.substring(0, pos + 2).length == 2) { year = parseInt("20" + val.substring(0, pos + 2), 10); } if (tmstmp === true) { if (year < 1978) { return false; } if (year > 2038 || (year > 2037 && day > 19 && month >= 1) || (year > 2037 && month > 1)) { return false; } } } else { return false; } return true; } /* function to check the validity of time * The following patterns are accepted in this validation (accepted in mysql as well) * 1) 2:3:4 * 2) 2:23:43 * 3) 2:23:43.123456 */ function isTime(val) { var arrayVal = val.split(":"); for (var a = 0, l = arrayVal.length; a < l; a++) { if (arrayVal[a].length == 1) { arrayVal[a] = fractionReplace(arrayVal[a]); } } val = arrayVal.join(":"); var tmexp = new RegExp(/^(-)?(([0-7]?[0-9][0-9])|(8[0-2][0-9])|(83[0-8])):((0[0-9])|([1-5][0-9])):((0[0-9])|([1-5][0-9]))(\.[0-9]{1,6}){0,1}$/); return tmexp.test(val); } /** * To check whether insert section is ignored or not */ function checkForCheckbox(multi_edit) { if($("#insert_ignore_"+multi_edit).length) { return $("#insert_ignore_"+multi_edit).is(":unchecked"); } return true; } function verificationsAfterFieldChange(urlField, multi_edit, theType) { var evt = window.event || arguments.callee.caller.arguments[0]; var target = evt.target || evt.srcElement; var $this_input = $(":input[name^='fields[multi_edit][" + multi_edit + "][" + urlField + "]']"); // the function drop-down that corresponds to this input field var $this_function = $("select[name='funcs[multi_edit][" + multi_edit + "][" + urlField + "]']"); var function_selected = false; if (typeof $this_function.val() !== 'undefined' && $this_function.val() !== null && $this_function.val().length > 0 ) { function_selected = true; } //To generate the textbox that can take the salt var new_salt_box = "
"; //If encrypting or decrypting functions that take salt as input is selected append the new textbox for salt if (target.value === 'AES_ENCRYPT' || target.value === 'AES_DECRYPT' || target.value === 'DES_ENCRYPT' || target.value === 'DES_DECRYPT' || target.value === 'ENCRYPT') { if (!($("#salt_" + target.id).length)) { $this_input.after(new_salt_box); } } else { //Remove the textbox for salt $('#salt_' + target.id).prev('br').remove(); $("#salt_" + target.id).remove(); } if (target.value === 'AES_DECRYPT' || target.value === 'AES_ENCRYPT' || target.value === 'MD5') { $('#' + target.id).rules("add", { validationFunctionForFuns: { param: $this_input, depends: function() { return checkForCheckbox(multi_edit); } } }); } // Unchecks the corresponding "NULL" control $("input[name='fields_null[multi_edit][" + multi_edit + "][" + urlField + "]']").prop('checked', false); // Unchecks the Ignore checkbox for the current row $("input[name='insert_ignore_" + multi_edit + "']").prop('checked', false); var charExceptionHandling; if (theType.substring(0,4) === "char") { charExceptionHandling = theType.substring(5,6); } else if (theType.substring(0,7) === "varchar") { charExceptionHandling = theType.substring(8,9); } if (function_selected) { $this_input.removeAttr('min'); $this_input.removeAttr('max'); // @todo: put back attributes if corresponding function is deselected } if ($this_input.data('rulesadded') == null && ! function_selected) { //call validate before adding rules $($this_input[0].form).validate(); // validate for date time if (theType == "datetime" || theType == "time" || theType == "date" || theType == "timestamp") { $this_input.rules("add", { validationFunctionForDateTime: { param: theType, depends: function() { return checkForCheckbox(multi_edit); } } }); } //validation for integer type if ($this_input.data('type') === 'INT') { var mini = parseInt($this_input.attr('min')); var maxi = parseInt($this_input.attr('max')); $this_input.rules("add", { number: { param : true, depends: function() { return checkForCheckbox(multi_edit); } }, min: { param: mini, depends: function() { if (isNaN($this_input.val())) { return false; } else { return checkForCheckbox(multi_edit); } } }, max: { param: maxi, depends: function() { if (isNaN($this_input.val())) { return false; } else { return checkForCheckbox(multi_edit); } } } }); //validation for CHAR types } else if ($this_input.data('type') === 'CHAR') { var maxlen = $this_input.data('maxlength'); if (typeof maxlen !== 'undefined') { if (maxlen <=4) { maxlen=charExceptionHandling; } $this_input.rules("add", { maxlength: { param: maxlen, depends: function() { return checkForCheckbox(multi_edit); } } }); } // validate binary & blob types } else if ($this_input.data('type') === 'HEX') { $this_input.rules("add", { validationFunctionForHex: { param: true, depends: function() { return checkForCheckbox(multi_edit); } } }); } $this_input.data('rulesadded', true); } else if ($this_input.data('rulesadded') == true && function_selected) { // remove any rules added $this_input.rules("remove"); // remove any error messages $this_input .removeClass('error') .removeAttr('aria-invalid') .siblings('.error') .remove(); $this_input.data('rulesadded', null); } } /* End of fields validation*/ /** * Unbind all event handlers before tearing down a page */ AJAX.registerTeardown('tbl_change.js', function () { $(document).off('click', 'span.open_gis_editor'); $(document).off('click', "input[name^='insert_ignore_']"); $(document).off('click', "input[name='gis_data[save]']"); $(document).off('click', 'input.checkbox_null'); $('select[name="submit_type"]').unbind('change'); $(document).off('change', "#insert_rows"); }); /** * Ajax handlers for Change Table page * * Actions Ajaxified here: * Submit Data to be inserted into the table. * Restart insertion with 'N' rows. */ AJAX.registerOnload('tbl_change.js', function () { if($("#insertForm").length) { // validate the comment form when it is submitted $("#insertForm").validate(); jQuery.validator.addMethod("validationFunctionForHex", function(value, element) { return value.match(/^[a-f0-9]*$/i) !== null; }); jQuery.validator.addMethod("validationFunctionForFuns", function(value, element, options) { if (value.substring(0, 3) === "AES" && options.data('type') !== 'HEX') { return false; } return !(value.substring(0, 3) === "MD5" && typeof options.data('maxlength') !== 'undefined' && options.data('maxlength') < 32); }); jQuery.validator.addMethod("validationFunctionForDateTime", function(value, element, options) { var dt_value = value; var theType = options; if (theType == "date") { return isDate(dt_value); } else if (theType == "time") { return isTime(dt_value); } else if (theType == "datetime" || theType == "timestamp") { var tmstmp = false; dt_value = dt_value.trim(); if (dt_value == "CURRENT_TIMESTAMP") { return true; } if (theType == "timestamp") { tmstmp = true; } if (dt_value == "0000-00-00 00:00:00") { return true; } var dv = dt_value.indexOf(" "); if (dv == -1) { // Only the date component, which is valid return isDate(dt_value, tmstmp); } return isDate(dt_value.substring(0, dv), tmstmp) && isTime(dt_value.substring(dv + 1)); } }); /* * message extending script must be run * after initiation of functions */ extendingValidatorMessages(); } $.datepicker.initialized = false; $(document).on('click', 'span.open_gis_editor', function (event) { event.preventDefault(); var $span = $(this); // Current value var value = $span.parent('td').children("input[type='text']").val(); // Field name var field = $span.parents('tr').children('td:first').find("input[type='hidden']").val(); // Column type var type = $span.parents('tr').find('span.column_type').text(); // Names of input field and null checkbox var input_name = $span.parent('td').children("input[type='text']").attr('name'); //Token var token = $("input[name='token']").val(); openGISEditor(); if (!gisEditorLoaded) { loadJSAndGISEditor(value, field, type, input_name, token); } else { loadGISEditor(value, field, type, input_name, token); } }); /** * Forced validation check of fields */ $(document).on('click',"input[name^='insert_ignore_']", function (event) { $("#insertForm").valid(); }); /** * Uncheck the null checkbox as geometry data is placed on the input field */ $(document).on('click', "input[name='gis_data[save]']", function (event) { var input_name = $('form#gis_data_editor_form').find("input[name='input_name']").val(); var $null_checkbox = $("input[name='" + input_name + "']").parents('tr').find('.checkbox_null'); $null_checkbox.prop('checked', false); }); /** * Handles all current checkboxes for Null; this only takes care of the * checkboxes on currently displayed rows as the rows generated by * "Continue insertion" are handled in the "Continue insertion" code * */ $(document).on('click', 'input.checkbox_null', function () { nullify( // use hidden fields populated by tbl_change.php $(this).siblings('.nullify_code').val(), $(this).closest('tr').find('input:hidden').first().val(), $(this).siblings('.hashed_field').val(), $(this).siblings('.multi_edit').val() ); }); /** * Reset the auto_increment column to 0 when selecting any of the * insert options in submit_type-dropdown. Only perform the reset * when we are in edit-mode, and not in insert-mode(no previous value * available). */ $('select[name="submit_type"]').bind('change', function () { var thisElemSubmitTypeVal = $(this).val(); var $table = $('table.insertRowTable'); var auto_increment_column = $table.find('input[name^="auto_increment"]'); auto_increment_column.each(function () { var $thisElemAIField = $(this); var thisElemName = $thisElemAIField.attr('name'); var prev_value_field = $table.find('input[name="' + thisElemName.replace('auto_increment', 'fields_prev') + '"]'); var value_field = $table.find('input[name="' + thisElemName.replace('auto_increment', 'fields') + '"]'); var previous_value = $(prev_value_field).val(); if (previous_value !== undefined) { if (thisElemSubmitTypeVal == 'insert' || thisElemSubmitTypeVal == 'insertignore' || thisElemSubmitTypeVal == 'showinsert' ) { $(value_field).val(0); } else { $(value_field).val(previous_value); } } }); }); /** * Continue Insertion form */ $(document).on('change', "#insert_rows", function (event) { event.preventDefault(); /** * @var columnCount Number of number of columns table has. */ var columnCount = $("table.insertRowTable:first").find("tr").has("input[name*='fields_name']").length; /** * @var curr_rows Number of current insert rows already on page */ var curr_rows = $("table.insertRowTable").length; /** * @var target_rows Number of rows the user wants */ var target_rows = $("#insert_rows").val(); // remove all datepickers $('input.datefield, input.datetimefield').each(function () { $(this).datepicker('destroy'); }); if (curr_rows < target_rows) { var tempIncrementIndex = function () { var $this_element = $(this); /** * Extract the index from the name attribute for all input/select fields and increment it * name is of format funcs[multi_edit][10][] */ /** * @var this_name String containing name of the input/select elements */ var this_name = $this_element.attr('name'); /** split {@link this_name} at [10], so we have the parts that can be concatenated later */ var name_parts = this_name.split(/\[\d+\]/); /** extract the [10] from {@link name_parts} */ var old_row_index_string = this_name.match(/\[\d+\]/)[0]; /** extract 10 - had to split into two steps to accomodate double digits */ var old_row_index = parseInt(old_row_index_string.match(/\d+/)[0], 10); /** calculate next index i.e. 11 */ new_row_index = old_row_index + 1; /** generate the new name i.e. funcs[multi_edit][11][foobarbaz] */ var new_name = name_parts[0] + '[' + new_row_index + ']' + name_parts[1]; var hashed_field = name_parts[1].match(/\[(.+)\]/)[1]; $this_element.attr('name', new_name); /** If element is select[name*='funcs'], update id */ if ($this_element.is("select[name*='funcs']")) { var this_id = $this_element.attr("id"); var id_parts = this_id.split(/\_/); var old_id_index = id_parts[1]; var prevSelectedValue = $("#field_" + old_id_index + "_1").val(); var new_id_index = parseInt(old_id_index) + columnCount; var new_id = 'field_' + new_id_index + '_1'; $this_element.attr('id', new_id); $this_element.find("option").filter(function () { return $(this).text() === prevSelectedValue; }).attr("selected","selected"); // If salt field is there then update its id. var nextSaltInput = $this_element.parent().next("td").next("td").find("input[name*='salt']"); if (nextSaltInput.length !== 0) { nextSaltInput.attr("id", "salt_" + new_id); } } // handle input text fields and textareas if ($this_element.is('.textfield') || $this_element.is('.char') || $this_element.is('textarea')) { // do not remove the 'value' attribute for ENUM columns // special handling for radio fields after updating ids to unique - see below if ($this_element.closest('tr').find('span.column_type').html() != 'enum') { $this_element.val($this_element.closest('tr').find('span.default_value').html()); } $this_element .unbind('change') // Remove onchange attribute that was placed // by tbl_change.php; it refers to the wrong row index .attr('onchange', null) // Keep these values to be used when the element // will change .data('hashed_field', hashed_field) .data('new_row_index', new_row_index) .bind('change', function () { var $changed_element = $(this); verificationsAfterFieldChange( $changed_element.data('hashed_field'), $changed_element.data('new_row_index'), $changed_element.closest('tr').find('span.column_type').html() ); }); } if ($this_element.is('.checkbox_null')) { $this_element // this event was bound earlier by jQuery but // to the original row, not the cloned one, so unbind() .unbind('click') // Keep these values to be used when the element // will be clicked .data('hashed_field', hashed_field) .data('new_row_index', new_row_index) .bind('click', function () { var $changed_element = $(this); nullify( $changed_element.siblings('.nullify_code').val(), $this_element.closest('tr').find('input:hidden').first().val(), $changed_element.data('hashed_field'), '[multi_edit][' + $changed_element.data('new_row_index') + ']' ); }); } }; var tempReplaceAnchor = function () { var $anchor = $(this); var new_value = 'rownumber=' + new_row_index; // needs improvement in case something else inside // the href contains this pattern var new_href = $anchor.attr('href').replace(/rownumber=\d+/, new_value); $anchor.attr('href', new_href); }; while (curr_rows < target_rows) { /** * @var $last_row Object referring to the last row */ var $last_row = $("#insertForm").find(".insertRowTable:last"); // need to access this at more than one level // (also needs improvement because it should be calculated // just once per cloned row, not once per column) var new_row_index = 0; //Clone the insert tables $last_row .clone(true, true) .insertBefore("#actions_panel") .find('input[name*=multi_edit],select[name*=multi_edit],textarea[name*=multi_edit]') .each(tempIncrementIndex) .end() .find('.foreign_values_anchor') .each(tempReplaceAnchor); //Insert/Clone the ignore checkboxes if (curr_rows == 1) { $('') .insertBefore("table.insertRowTable:last") .after(''); } else { /** * @var $last_checkbox Object reference to the last checkbox in #insertForm */ var $last_checkbox = $("#insertForm").children('input:checkbox:last'); /** name of {@link $last_checkbox} */ var last_checkbox_name = $last_checkbox.attr('name'); /** index of {@link $last_checkbox} */ var last_checkbox_index = parseInt(last_checkbox_name.match(/\d+/), 10); /** name of new {@link $last_checkbox} */ var new_name = last_checkbox_name.replace(/\d+/, last_checkbox_index + 1); $('
') .insertBefore("table.insertRowTable:last"); $last_checkbox .clone() .attr({'id': new_name, 'name': new_name}) .prop('checked', true) .insertBefore("table.insertRowTable:last"); $('label[for^=insert_ignore]:last') .clone() .attr('for', new_name) .insertBefore("table.insertRowTable:last"); $('
') .insertBefore("table.insertRowTable:last"); } curr_rows++; } // recompute tabindex for text fields and other controls at footer; // IMO it's not really important to handle the tabindex for // function and Null var tabindex = 0; $('.textfield, .char, textarea') .each(function () { tabindex++; $(this).attr('tabindex', tabindex); // update the IDs of textfields to ensure that they are unique $(this).attr('id', "field_" + tabindex + "_3"); // special handling for radio fields after updating ids to unique if ($(this).closest('tr').find('span.column_type').html() === 'enum') { if ($(this).val() === $(this).closest('tr').find('span.default_value').html()) { $(this).prop('checked', true); } else { $(this).prop('checked', false); } } }); $('.control_at_footer') .each(function () { tabindex++; $(this).attr('tabindex', tabindex); }); } else if (curr_rows > target_rows) { while (curr_rows > target_rows) { $("input[id^=insert_ignore]:last") .nextUntil("fieldset") .addBack() .remove(); curr_rows--; } } // Add all the required datepickers back addDateTimePicker(); }); }); function changeValueFieldType(elem, searchIndex) { var fieldsValue = $("select#fieldID_" + searchIndex); if (0 === fieldsValue.size()) { return; } var type = $(elem).val(); if ('IN (...)' == type || 'NOT IN (...)' == type || 'BETWEEN' == type || 'NOT BETWEEN' == type ) { $("#fieldID_" + searchIndex).attr('multiple', ''); } else { $("#fieldID_" + searchIndex).removeAttr('multiple'); } }