lib_head.js.php 37 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109
  1. <?php
  2. /* Copyright (C) 2005-2018 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2005-2014 Regis Houssin <regis.houssin@inodbox.com>
  4. * Copyright (C) 2015 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. * or see https://www.gnu.org/
  19. */
  20. /**
  21. * \file htdocs/core/js/lib_head.js.php
  22. * \brief File that include javascript functions (included if option use_javascript activated)
  23. * JQuery (providing object $) and JQuery-UI (providing $datepicker) libraries must be loaded before this file.
  24. */
  25. if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC', '1');
  26. if (! defined('NOCSRFCHECK')) define('NOCSRFCHECK', 1);
  27. if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL', 1);
  28. if (! defined('NOLOGIN')) define('NOLOGIN', 1);
  29. if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU', 1);
  30. if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML', 1);
  31. if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX', '1');
  32. session_cache_limiter('public');
  33. require_once '../../main.inc.php';
  34. // Define javascript type
  35. top_httphead('text/javascript; charset=UTF-8');
  36. // Important: Following code is to avoid page request by browser and PHP CPU at each Dolibarr page access.
  37. if (empty($dolibarr_nocache)) header('Cache-Control: max-age=10800, public, must-revalidate');
  38. else header('Cache-Control: no-cache');
  39. // Define tradMonths javascript array (we define this in datepicker AND in parent page to avoid errors with IE8)
  40. $tradMonths=array(
  41. dol_escape_js($langs->transnoentitiesnoconv("Month01")),
  42. dol_escape_js($langs->transnoentitiesnoconv("Month02")),
  43. dol_escape_js($langs->transnoentitiesnoconv("Month03")),
  44. dol_escape_js($langs->transnoentitiesnoconv("Month04")),
  45. dol_escape_js($langs->transnoentitiesnoconv("Month05")),
  46. dol_escape_js($langs->transnoentitiesnoconv("Month06")),
  47. dol_escape_js($langs->transnoentitiesnoconv("Month07")),
  48. dol_escape_js($langs->transnoentitiesnoconv("Month08")),
  49. dol_escape_js($langs->transnoentitiesnoconv("Month09")),
  50. dol_escape_js($langs->transnoentitiesnoconv("Month10")),
  51. dol_escape_js($langs->transnoentitiesnoconv("Month11")),
  52. dol_escape_js($langs->transnoentitiesnoconv("Month12"))
  53. );
  54. $tradMonthsShort=array(
  55. $langs->trans("MonthShort01"),
  56. $langs->trans("MonthShort02"),
  57. $langs->trans("MonthShort03"),
  58. $langs->trans("MonthShort04"),
  59. $langs->trans("MonthShort05"),
  60. $langs->trans("MonthShort06"),
  61. $langs->trans("MonthShort07"),
  62. $langs->trans("MonthShort08"),
  63. $langs->trans("MonthShort09"),
  64. $langs->trans("MonthShort10"),
  65. $langs->trans("MonthShort11"),
  66. $langs->trans("MonthShort12")
  67. );
  68. $tradDays=array(
  69. $langs->trans("Sunday"),
  70. $langs->trans("Monday"),
  71. $langs->trans("Tuesday"),
  72. $langs->trans("Wednesday"),
  73. $langs->trans("Thursday"),
  74. $langs->trans("Friday"),
  75. $langs->trans("Saturday")
  76. );
  77. $tradDaysShort=array(
  78. $langs->trans("ShortSunday"),
  79. $langs->trans("ShortMonday"),
  80. $langs->trans("ShortTuesday"),
  81. $langs->trans("ShortWednesday"),
  82. $langs->trans("ShortThursday"),
  83. $langs->trans("ShortFriday"),
  84. $langs->trans("ShortSaturday")
  85. );
  86. $tradDaysMin=array(
  87. $langs->trans("SundayMin"),
  88. $langs->trans("MondayMin"),
  89. $langs->trans("TuesdayMin"),
  90. $langs->trans("WednesdayMin"),
  91. $langs->trans("ThursdayMin"),
  92. $langs->trans("FridayMin"),
  93. $langs->trans("SaturdayMin")
  94. );
  95. ?>
  96. // Javascript libraries for Dolibarr ERP CRM (https://www.dolibarr.org)
  97. // For jQuery date picker
  98. var tradMonths = <?php echo json_encode($tradMonths) ?>;
  99. var tradMonthsShort = <?php echo json_encode($tradMonthsShort) ?>;
  100. var tradDays = <?php echo json_encode($tradDays) ?>;
  101. var tradDaysShort = <?php echo json_encode($tradDaysShort) ?>;
  102. var tradDaysMin = <?php echo json_encode($tradDaysMin) ?>;
  103. // For JQuery date picker
  104. $(document).ready(function() {
  105. $.datepicker.setDefaults({
  106. autoSize: true,
  107. changeMonth: true,
  108. changeYear: true,
  109. altField: '#timestamp',
  110. altFormat: '@' // Gives a timestamp dateformat
  111. });
  112. });
  113. jQuery(function($){
  114. $.datepicker.regional['<?php echo $langs->defaultlang ?>'] = {
  115. closeText: '<?php echo $langs->trans("Close2") ?>',
  116. prevText: '<?php echo $langs->trans("Previous") ?>',
  117. nextText: '<?php echo $langs->trans("Next") ?>',
  118. currentText: '<?php echo $langs->trans("Now") ?>',
  119. monthNames: tradMonths,
  120. monthNamesShort: tradMonthsShort,
  121. dayNames: tradDays,
  122. dayNamesShort: tradDaysShort,
  123. dayNamesMin: tradDaysMin,
  124. weekHeader: '<?php echo $langs->trans("Week"); ?>',
  125. dateFormat: '<?php echo $langs->trans("FormatDateShortJQuery"); ?>', /* Note dd/mm/yy means year on 4 digit in jquery format */
  126. firstDay: <?php echo (isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1'); ?>,
  127. isRTL: <?php echo ($langs->trans("DIRECTION")=='rtl'?'true':'false'); ?>,
  128. showMonthAfterYear: false, /* TODO add specific to country */
  129. yearSuffix: '' /* TODO add specific to country */
  130. };
  131. $.datepicker.setDefaults($.datepicker.regional['<?php echo $langs->defaultlang ?>']);
  132. });
  133. /**
  134. * Set array used for select2 translations
  135. */
  136. var select2arrayoflanguage = {
  137. matches: function (matches) { return matches + " <?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2ResultFoundUseArrows")); ?>"; },
  138. noResults: function () { return "<?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2NotFound")); ?>"; },
  139. inputTooShort: function (input) {
  140. var n = input.minimum;
  141. /*console.log(input);
  142. console.log(input.minimum);*/
  143. if (n > 1) return "<?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2Enter")); ?> " + n + " <?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2MoreCharacters")); ?>";
  144. else return "<?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2Enter")); ?> " + n + " <?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2MoreCharacter")); ?>"
  145. },
  146. loadMore: function (pageNumber) { return "<?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2LoadingMoreResults")); ?>"; },
  147. searching: function () { return "<?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2SearchInProgress")); ?>"; }
  148. };
  149. /**
  150. * For calendar input
  151. */
  152. // Returns an object given an id
  153. function getObjectFromID(id){
  154. var theObject;
  155. if(document.getElementById)
  156. theObject=document.getElementById(id);
  157. else
  158. theObject=document.all[id];
  159. return theObject;
  160. }
  161. // Called after selection of a date to save details into detailed fields
  162. function dpChangeDay(dateFieldID,format)
  163. {
  164. //showDP.datefieldID=dateFieldID;
  165. console.log("Call dpChangeDay, we save date into detailed fields.");
  166. var thefield=getObjectFromID(dateFieldID);
  167. var thefieldday=getObjectFromID(dateFieldID+"day");
  168. var thefieldmonth=getObjectFromID(dateFieldID+"month");
  169. var thefieldyear=getObjectFromID(dateFieldID+"year");
  170. var date=getDateFromFormat(thefield.value,format);
  171. if (date)
  172. {
  173. thefieldday.value=date.getDate();
  174. if(thefieldday.onchange) thefieldday.onchange.call(thefieldday);
  175. thefieldmonth.value=date.getMonth()+1;
  176. if(thefieldmonth.onchange) thefieldmonth.onchange.call(thefieldmonth);
  177. thefieldyear.value=date.getFullYear();
  178. if(thefieldyear.onchange) thefieldyear.onchange.call(thefieldyear);
  179. }
  180. else
  181. {
  182. thefieldday.value='';
  183. if(thefieldday.onchange) thefieldday.onchange.call(thefieldday);
  184. thefieldmonth.value='';
  185. if(thefieldmonth.onchange) thefieldmonth.onchange.call(thefieldmonth);
  186. thefieldyear.value='';
  187. if(thefieldyear.onchange) thefieldyear.onchange.call(thefieldyear);
  188. }
  189. }
  190. /*
  191. * =================================================================
  192. * Function:
  193. * formatDate (javascript object Date(), format) Purpose: Returns a date in the
  194. * output format specified. The format string can use the following tags: Field |
  195. * Tags -------------+------------------------------- Year | yyyy (4 digits), yy
  196. * (2 digits) Month | MM (2 digits) Day of Month | dd (2 digits) Hour (1-12) |
  197. * hh (2 digits) Hour (0-23) | HH (2 digits) Minute | mm (2 digits) Second | ss
  198. * (2 digits) Author: Laurent Destailleur Author: Matelli (see
  199. * http://matelli.fr/showcases/patchs-dolibarr/update-date-input-in-action-form.html)
  200. * Licence: GPL
  201. * ==================================================================
  202. */
  203. function formatDate(date,format)
  204. {
  205. // alert('formatDate date='+date+' format='+format);
  206. // Force parametres en chaine
  207. format=format+"";
  208. var result="";
  209. var year=date.getYear()+""; if (year.length < 4) { year=""+(year-0+1900); }
  210. var month=date.getMonth()+1;
  211. var day=date.getDate();
  212. var hour=date.getHours();
  213. var minute=date.getMinutes();
  214. var seconde=date.getSeconds();
  215. var i=0;
  216. while (i < format.length)
  217. {
  218. c=format.charAt(i); // Recupere char du format
  219. substr="";
  220. j=i;
  221. while ((format.charAt(j)==c) && (j < format.length)) // Recupere char successif identiques
  222. {
  223. substr += format.charAt(j++);
  224. }
  225. // alert('substr='+substr);
  226. if (substr == 'yyyy') { result=result+year; }
  227. else if (substr == 'yy') { result=result+year.substring(2,4); }
  228. else if (substr == 'M') { result=result+month; }
  229. else if (substr == 'MM') { result=result+(month<1||month>9?"":"0")+month; }
  230. else if (substr == 'd') { result=result+day; }
  231. else if (substr == 'dd') { result=result+(day<1||day>9?"":"0")+day; }
  232. else if (substr == 'hh') { if (hour > 12) hour-=12; result=result+(hour<0||hour>9?"":"0")+hour; }
  233. else if (substr == 'HH') { result=result+(hour<0||hour>9?"":"0")+hour; }
  234. else if (substr == 'mm') { result=result+(minute<0||minute>9?"":"0")+minute; }
  235. else if (substr == 'ss') { result=result+(seconde<0||seconde>9?"":"0")+seconde; }
  236. else { result=result+substr; }
  237. i+=substr.length;
  238. }
  239. // alert(result);
  240. return result;
  241. }
  242. /*
  243. * =================================================================
  244. * Function: getDateFromFormat(date_string, format_string)
  245. * Purpose: This function takes a date string and a format string.
  246. * It parses the date string with format and it
  247. * returns the date as a javascript Date() object. If date does not match
  248. * format, it returns 0. The format string can use the following tags:
  249. * Field | Tags
  250. * -------------+-----------------------------------
  251. * Year | yyyy (4 digits), yy (2 digits)
  252. * Month | MM (2 digits)
  253. * Day of Month | dd (2 digits)
  254. * Hour (1-12) | hh (2 digits)
  255. * Hour (0-23) | HH (2 digits)
  256. * Minute | mm (2 digits)
  257. * Second | ss (2 digits)
  258. * Author: Laurent Destailleur
  259. * Licence: GPL
  260. * ==================================================================
  261. */
  262. function getDateFromFormat(val,format)
  263. {
  264. // alert('getDateFromFormat val='+val+' format='+format);
  265. // Force parametres en chaine
  266. val=val+"";
  267. format=format+"";
  268. if (val == '') return 0;
  269. var now=new Date();
  270. var year=now.getYear(); if (year.length < 4) { year=""+(year-0+1900); }
  271. var month=now.getMonth()+1;
  272. var day=now.getDate();
  273. var hour=now.getHours();
  274. var minute=now.getMinutes();
  275. var seconde=now.getSeconds();
  276. var i=0;
  277. var d=0; // -d- follows the date string while -i- follows the format
  278. // string
  279. while (i < format.length)
  280. {
  281. c=format.charAt(i); // Recupere char du format
  282. substr="";
  283. j=i;
  284. while ((format.charAt(j)==c) && (j < format.length)) // Recupere char
  285. // successif
  286. // identiques
  287. {
  288. substr += format.charAt(j++);
  289. }
  290. // alert('substr='+substr);
  291. if (substr == "yyyy") year=getIntegerInString(val,d,4,4);
  292. if (substr == "yy") year=""+(getIntegerInString(val,d,2,2)-0+1900);
  293. if (substr == "MM" ||substr == "M")
  294. {
  295. month=getIntegerInString(val,d,1,2);
  296. if (month) d -= 2- month.length;
  297. }
  298. if (substr == "dd")
  299. {
  300. day=getIntegerInString(val,d,1,2);
  301. if (day) d -= 2- day.length;
  302. }
  303. if (substr == "HH" ||substr == "hh" )
  304. {
  305. hour=getIntegerInString(val,d,1,2);
  306. if (dhouray) d -= 2- hour.length;
  307. }
  308. if (substr == "mm"){
  309. minute=getIntegerInString(val,d,1,2);
  310. if (minute) d -= 2- minute.length;
  311. }
  312. if (substr == "ss")
  313. {
  314. seconde=getIntegerInString(val,d,1,2);
  315. if (seconde) d -= 2- seconde.length;
  316. }
  317. i+=substr.length;
  318. d+=substr.length;
  319. }
  320. // Check if format param are ok
  321. if (year==null||year<1) { return 0; }
  322. if (month==null||(month<1)||(month>12)) { return 0; }
  323. if (day==null||(day<1)||(day>31)) { return 0; }
  324. if (hour==null||(hour<0)||(hour>24)) { return 0; }
  325. if (minute==null||(minute<0)||(minute>60)) { return 0; }
  326. if (seconde==null||(seconde<0)||(seconde>60)) { return 0; }
  327. // alert(year+' '+month+' '+day+' '+hour+' '+minute+' '+seconde);
  328. return new Date(year,month-1,day,hour,minute,seconde);
  329. }
  330. /*
  331. * =================================================================
  332. * Function: stringIsInteger(string)
  333. * Purpose: Return true if string is an integer
  334. * ==================================================================
  335. */
  336. function stringIsInteger(str)
  337. {
  338. var digits="1234567890";
  339. for (var i=0; i < str.length; i++)
  340. {
  341. if (digits.indexOf(str.charAt(i))==-1)
  342. {
  343. return false;
  344. }
  345. }
  346. return true;
  347. }
  348. /*
  349. * =================================================================
  350. * Function: getIntegerInString(string,pos,minlength,maxlength)
  351. * Purpose: Return part of string from position i that is integer
  352. * ==================================================================
  353. */
  354. function getIntegerInString(str,i,minlength,maxlength)
  355. {
  356. for (var x=maxlength; x>=minlength; x--)
  357. {
  358. var substr=str.substring(i,i+x);
  359. if (substr.length < minlength) { return null; }
  360. if (stringIsInteger(substr)) { return substr; }
  361. }
  362. return null;
  363. }
  364. /*
  365. * =================================================================
  366. * Purpose: Clean string to have it url encoded
  367. * Input: s
  368. * Author: Laurent Destailleur
  369. * Licence: GPL
  370. * ==================================================================
  371. */
  372. function urlencode(s) {
  373. news=s;
  374. news=news.replace(/\+/gi,'%2B');
  375. news=news.replace(/&/gi,'%26');
  376. return news;
  377. }
  378. /*
  379. * =================================================================
  380. * Purpose: Clean string to have it url encoded
  381. * Input: s
  382. * Author: Laurent Destailleur
  383. * Licence: GPL
  384. * ==================================================================
  385. */
  386. function htmlEntityDecodeJs(inp){
  387. var replacements = {'&lt;':'<','&gt;':'>','&sol;':'/','&quot;':'"','&apos;':'\'','&amp;':'&','&nbsp;':' '};
  388. if (inp)
  389. {
  390. for(var r in replacements){
  391. inp = inp.replace(new RegExp(r,'g'),replacements[r]);
  392. }
  393. return inp.replace(/&#(\d+);/g, function(match, dec) {
  394. return String.fromCharCode(dec);
  395. });
  396. }
  397. else { return ''; }
  398. }
  399. /*
  400. * =================================================================
  401. * Purpose: Applique un delai avant execution. Used for autocompletion of companies.
  402. * Input: funct, delay
  403. * Author: Regis Houssin
  404. * Licence: GPL
  405. * ==================================================================
  406. */
  407. function ac_delay(funct,delay) {
  408. // delay before start of action
  409. setTimeout(funct,delay);
  410. }
  411. /*
  412. * =================================================================
  413. * Purpose:
  414. * Clean values of a "Sortable.serialize". Used by drag and drop.
  415. * Input: expr
  416. * Author: Regis Houssin
  417. * Licence: GPL
  418. * ==================================================================
  419. */
  420. function cleanSerialize(expr) {
  421. if (typeof(expr) != 'string') return '';
  422. var reg = new RegExp("(&)", "g");
  423. var reg2 = new RegExp("[^A-Z0-9,]", "g");
  424. var liste1 = expr.replace(reg, ",");
  425. return liste1.replace(reg2, "");
  426. }
  427. /*
  428. * =================================================================
  429. * Purpose: Display a temporary message in input text fields (For showing help message on
  430. * input field).
  431. * Input: fieldId
  432. * Input: message
  433. * Author: Regis Houssin
  434. * Licence: GPL
  435. * ==================================================================
  436. */
  437. function displayMessage(fieldId,message) {
  438. var textbox = document.getElementById(fieldId);
  439. if (textbox.value == '') {
  440. textbox.style.color = 'grey';
  441. textbox.value = message;
  442. }
  443. }
  444. /*
  445. * =================================================================
  446. * Purpose: Hide a temporary message in input text fields (For showing help message on
  447. * input field).
  448. * Input: fiedId
  449. * Input: message
  450. * Author: Regis Houssin
  451. * Licence: GPL
  452. * ==================================================================
  453. */
  454. function hideMessage(fieldId,message) {
  455. var textbox = document.getElementById(fieldId);
  456. textbox.style.color = 'black';
  457. if (textbox.value == message) textbox.value = '';
  458. }
  459. /*
  460. * Used by button to set on/off
  461. *
  462. * @param string url Url
  463. * @param string code Code
  464. * @param string intput Input
  465. * @param int entity Entity
  466. * @param int strict Strict
  467. */
  468. function setConstant(url, code, input, entity, strict) {
  469. $.get( url, {
  470. action: "set",
  471. name: code,
  472. entity: entity
  473. },
  474. function() {
  475. $("#set_" + code).hide();
  476. $("#del_" + code).show();
  477. $.each(input, function(type, data) {
  478. // Enable another element
  479. if (type == "disabled" && strict != 1) {
  480. $.each(data, function(key, value) {
  481. var newvalue=((value.search("^#") < 0 && value.search("^\.") < 0) ? "#" : "") + value;
  482. $(newvalue).removeAttr("disabled");
  483. if ($(newvalue).hasClass("butActionRefused") == true) {
  484. $(newvalue).removeClass("butActionRefused");
  485. $(newvalue).addClass("butAction");
  486. }
  487. });
  488. } else if (type == "enabled") {
  489. $.each(data, function(key, value) {
  490. var newvalue=((value.search("^#") < 0 && value.search("^\.") < 0) ? "#" : "") + value;
  491. if (strict == 1)
  492. $(newvalue).removeAttr("disabled");
  493. else
  494. $(newvalue).attr("disabled", true);
  495. if ($(newvalue).hasClass("butAction") == true) {
  496. $(newvalue).removeClass("butAction");
  497. $(newvalue).addClass("butActionRefused");
  498. }
  499. });
  500. // Show another element
  501. } else if (type == "showhide" || type == "show") {
  502. $.each(data, function(key, value) {
  503. var newvalue=((value.search("^#") < 0 && value.search("^\.") < 0) ? "#" : "") + value;
  504. $(newvalue).show();
  505. });
  506. // Set another constant
  507. } else if (type == "set") {
  508. $.each(data, function(key, value) {
  509. $("#set_" + key).hide();
  510. $("#del_" + key).show();
  511. $.get( url, {
  512. action: "set",
  513. name: key,
  514. value: value,
  515. entity: entity
  516. });
  517. });
  518. }
  519. });
  520. });
  521. }
  522. /*
  523. * Used by button to set on/off
  524. *
  525. * @param string url Url
  526. * @param string code Code
  527. * @param string intput Input
  528. * @param int entity Entity
  529. * @param int strict Strict
  530. */
  531. function delConstant(url, code, input, entity, strict) {
  532. $.get( url, {
  533. action: "del",
  534. name: code,
  535. entity: entity
  536. },
  537. function() {
  538. $("#del_" + code).hide();
  539. $("#set_" + code).show();
  540. $.each(input, function(type, data) {
  541. // Disable another element
  542. if (type == "disabled") {
  543. $.each(data, function(key, value) {
  544. var newvalue=((value.search("^#") < 0 && value.search("^\.") < 0) ? "#" : "") + value;
  545. $(newvalue).attr("disabled", true);
  546. if ($(newvalue).hasClass("butAction") == true) {
  547. $(newvalue).removeClass("butAction");
  548. $(newvalue).addClass("butActionRefused");
  549. }
  550. });
  551. } else if (type == "enabled" && strict != 1) {
  552. $.each(data, function(key, value) {
  553. var newvalue=((value.search("^#") < 0 && value.search("^\.") < 0) ? "#" : "") + value;
  554. $(newvalue).removeAttr("disabled");
  555. if ($(newvalue).hasClass("butActionRefused") == true) {
  556. $(newvalue).removeClass("butActionRefused");
  557. $(newvalue).addClass("butAction");
  558. }
  559. });
  560. // Hide another element
  561. } else if (type == "showhide" || type == "hide") {
  562. $.each(data, function(key, value) {
  563. var newvalue=((value.search("^#") < 0 && value.search("^\.") < 0) ? "#" : "") + value;
  564. $(newvalue).hide();
  565. });
  566. // Delete another constant
  567. } else if (type == "del") {
  568. $.each(data, function(key, value) {
  569. $("#del_" + value).hide();
  570. $("#set_" + value).show();
  571. $.get( url, {
  572. action: "del",
  573. name: value,
  574. entity: entity
  575. });
  576. });
  577. }
  578. });
  579. });
  580. }
  581. /*
  582. * Used by button to set on/off
  583. *
  584. * @param string action Action
  585. * @param string url Url
  586. * @param string code Code
  587. * @param string intput Input
  588. * @param string box Box
  589. * @param int entity Entity
  590. * @param int yesButton yesButton
  591. * @param int noButton noButton
  592. * @param int strict Strict
  593. */
  594. function confirmConstantAction(action, url, code, input, box, entity, yesButton, noButton, strict) {
  595. var boxConfirm = box;
  596. $("#confirm_" + code)
  597. .attr("title", boxConfirm.title)
  598. .html(boxConfirm.content)
  599. .dialog({
  600. resizable: false,
  601. height: 170,
  602. width: 500,
  603. modal: true,
  604. buttons: [
  605. {
  606. id : 'yesButton_' + code,
  607. text : yesButton,
  608. click : function() {
  609. if (action == "set") {
  610. setConstant(url, code, input, entity, strict);
  611. } else if (action == "del") {
  612. delConstant(url, code, input, entity, strict);
  613. }
  614. // Close dialog
  615. $(this).dialog("close");
  616. // Execute another method
  617. if (boxConfirm.method) {
  618. var fnName = boxConfirm.method;
  619. if (window.hasOwnProperty(fnName)) {
  620. window[fnName]();
  621. }
  622. }
  623. }
  624. },
  625. {
  626. id : 'noButton_' + code,
  627. text : noButton,
  628. click : function() {
  629. $(this).dialog("close");
  630. }
  631. }
  632. ]
  633. });
  634. // For information dialog box only, hide the noButton
  635. if (boxConfirm.info) {
  636. $("#noButton_" + code).button().hide();
  637. }
  638. }
  639. /*
  640. * =================================================================
  641. * This is to allow to transform all select box into ajax autocomplete box
  642. * with just one line:
  643. * $(function() { $( "#idofmylist" ).combobox(); });
  644. * Do not use it on large combo boxes
  645. * =================================================================
  646. */
  647. (function( $ ) {
  648. $.widget( "ui.combobox", {
  649. options: {
  650. minLengthToAutocomplete: 0
  651. },
  652. _create: function() {
  653. var savMinLengthToAutocomplete = this.options.minLengthToAutocomplete;
  654. var self = this,
  655. select = this.element.hide(),
  656. selected = select.children( ":selected" ),
  657. value = selected.val() ? selected.text() : "";
  658. var input = this.input = $( "<input>" )
  659. .insertAfter( select )
  660. .val( value )
  661. .attr('id', 'inputautocomplete'+select.attr('id'))
  662. .autocomplete({
  663. delay: 0,
  664. minLength: this.options.minLengthToAutocomplete,
  665. source: function( request, response ) {
  666. var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
  667. response( select.children( "option:enabled" ).map(function() {
  668. var text = $( this ).text();
  669. if ( this.value && ( !request.term || matcher.test(text) ) )
  670. return {
  671. label: text.replace(
  672. new RegExp(
  673. "(?![^&;]+;)(?!<[^<>]*)(" +
  674. $.ui.autocomplete.escapeRegex(request.term) +
  675. ")(?![^<>]*>)(?![^&;]+;)", "gi"
  676. ), "<strong>$1</strong>" ),
  677. value: text,
  678. option: this
  679. };
  680. }) );
  681. },
  682. select: function( event, ui ) {
  683. ui.item.option.selected = true;
  684. self._trigger( "selected", event, {
  685. item: ui.item.option
  686. });
  687. },
  688. change: function( event, ui ) {
  689. if ( !ui.item ) {
  690. var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" ),
  691. valid = false;
  692. select.children( "option" ).each(function() {
  693. if ( $( this ).text().match( matcher ) ) {
  694. this.selected = valid = true;
  695. return false;
  696. }
  697. });
  698. if ( !valid ) {
  699. // remove invalid value, as it didnt match anything
  700. $( this ).val( "" );
  701. select.val( "" );
  702. input.data("ui-autocomplete").term = "";
  703. return false;
  704. }
  705. }
  706. }
  707. })
  708. .addClass( "ui-widget ui-widget-content ui-corner-left dolibarrcombobox" );
  709. input.data("ui-autocomplete")._renderItem = function( ul, item ) {
  710. return $("<li>")
  711. .data( "ui-autocomplete-item", item ) // jQuery UI > 1.10.0
  712. .append( "<a>" + item.label + "</a>" )
  713. .appendTo( ul );
  714. };
  715. this.button = $( "<button type=\'button\'>&nbsp;</button>" )
  716. .attr( "tabIndex", -1 )
  717. .attr( "title", "Show All Items" )
  718. .insertAfter( input )
  719. .button({
  720. icons: {
  721. primary: "ui-icon-triangle-1-s"
  722. },
  723. text: false
  724. })
  725. .removeClass( "ui-corner-all" )
  726. .addClass( "ui-corner-right ui-button-icon" )
  727. .click(function() {
  728. // close if already visible
  729. if ( input.autocomplete( "widget" ).is( ":visible" ) ) {
  730. input.autocomplete( "close" );
  731. return;
  732. }
  733. // pass empty string as value to search for, displaying all results
  734. input.autocomplete({ minLength: 0 });
  735. input.autocomplete( "search", "" );
  736. input.autocomplete({ minLength: savMinLengthToAutocomplete });
  737. input.focus();
  738. });
  739. },
  740. destroy: function() {
  741. this.input.remove();
  742. this.button.remove();
  743. this.element.show();
  744. $.Widget.prototype.destroy.call( this );
  745. }
  746. });
  747. })( jQuery );
  748. /**
  749. * Function to output a dialog box for copy/paste
  750. *
  751. * @param string text Text to put into copy/paste area
  752. * @param string text2 Text to put under the copy/paste area
  753. */
  754. function copyToClipboard(text,text2)
  755. {
  756. text = text.replace(/<br>/g,"\n");
  757. var newElem = '<textarea id="coordsforpopup" style="border: none; width: 90%; height: 120px;">'+text+'</textarea><br><br>'+text2;
  758. /* alert(newElem); */
  759. $("#dialogforpopup").html(newElem);
  760. $("#dialogforpopup").dialog();
  761. $("#coordsforpopup").select();
  762. return false;
  763. }
  764. /**
  765. * Show a popup HTML page. Use the "window.open" function.
  766. *
  767. * @param string url Url
  768. * @param string title Title of popup
  769. * @return boolean False
  770. * @see document_preview
  771. */
  772. function newpopup(url, title) {
  773. var argv = newpopup.arguments;
  774. var argc = newpopup.arguments.length;
  775. tmp=url;
  776. console.log("newpopup "+argv[2]+" "+argv[3]);
  777. var l = (argc > 2) ? argv[2] : 600;
  778. var h = (argc > 3) ? argv[3] : 400;
  779. var left = (screen.width - l)/2;
  780. var top = (screen.height - h)/2;
  781. var wfeatures = "directories=0,menubar=0,status=0,resizable=0,scrollbars=1,toolbar=0,width=" + l +",height=" + h + ",left=" + left + ",top=" + top;
  782. fen=window.open(tmp,title,wfeatures);
  783. return false;
  784. }
  785. /**
  786. * Function show document preview. It uses the "dialog" function.
  787. * The a tag around the img must have the src='', class='documentpreview', mime='image/xxx', target='_blank' from getAdvancedPreviewUrl().
  788. *
  789. * @param string file Url
  790. * @param string type Mime file type ("image/jpeg", "application/pdf", "text/html")
  791. * @param string title Title of popup
  792. * @return void
  793. * @see newpopup
  794. */
  795. function document_preview(file, type, title)
  796. {
  797. var ValidImageTypes = ["image/gif", "image/jpeg", "image/png"];
  798. var showOriginalSizeButton = false;
  799. console.log("document_preview A click was done. file="+file+", type="+type+", title="+title);
  800. if ($.inArray(type, ValidImageTypes) < 0) {
  801. var width='85%';
  802. var object_width='100%';
  803. var height = ($( window ).height() - 60) * 0.90;
  804. var object_height='98%';
  805. show_preview('notimage');
  806. } else {
  807. var object_width=0;
  808. var object_height=0;
  809. var img = new Image();
  810. img.onload = function() {
  811. object_width = this.width;
  812. object_height = this.height;
  813. width = $( window ).width()*0.90;
  814. if(object_width < width){
  815. console.log("Object width is small, we set width of popup according to image width.");
  816. width = object_width + 30
  817. }
  818. height = $( window ).height()*0.85;
  819. if(object_height < height){
  820. console.log("Object height is small, we set height of popup according to image height.");
  821. height = object_height + 80
  822. }
  823. else
  824. {
  825. showOriginalSizeButton = true;
  826. }
  827. show_preview('image');
  828. };
  829. img.src = file;
  830. }
  831. function show_preview(mode) {
  832. /* console.log("mode="+mode+" file="+file+" type="+type+" width="+width+" height="+height); */
  833. var newElem = '<object name="objectpreview" data="'+file+'" type="'+type+'" width="'+object_width+'" height="'+object_height+'" param="noparam"></object>';
  834. optionsbuttons = {}
  835. if (mode == 'image' && showOriginalSizeButton)
  836. {
  837. optionsbuttons = {
  838. "<?php echo dol_escape_js($langs->transnoentitiesnoconv("OriginalSize")); ?>": function() { console.log("Click on original size"); jQuery(".ui-dialog-content.ui-widget-content > object").css({ "max-height": "none" }); },
  839. "<?php echo dol_escape_js($langs->transnoentitiesnoconv("CloseWindow")); ?>": function() { $( this ).dialog( "close" ); }
  840. };
  841. }
  842. $("#dialogforpopup").html(newElem);
  843. $("#dialogforpopup").dialog({
  844. closeOnEscape: true,
  845. resizable: true,
  846. width: width,
  847. height: height,
  848. modal: true,
  849. title: title,
  850. buttons: optionsbuttons
  851. });
  852. if (showOriginalSizeButton)
  853. {
  854. jQuery(".ui-dialog-content.ui-widget-content > object").css({ "max-height": "100%", "width": "auto", "margin-left": "auto", "margin-right": "auto", "display": "block" });
  855. }
  856. }
  857. }
  858. /*
  859. * Provide a function to get an URL GET parameter in javascript
  860. *
  861. * @param string name Name of parameter
  862. * @param mixed valueifnotfound Value if not found
  863. * @return string Value
  864. */
  865. function getParameterByName(name, valueifnotfound)
  866. {
  867. name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
  868. var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
  869. results = regex.exec(location.search);
  870. return results === null ? valueifnotfound : decodeURIComponent(results[1].replace(/\+/g, " "));
  871. }
  872. // Code in the public domain from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
  873. (function() {
  874. /**
  875. * Decimal adjustment of a number.
  876. *
  877. * @param {String} type The type of adjustment.
  878. * @param {Number} value The number.
  879. * @param {Integer} exp The exponent (the 10 logarithm of the adjustment base).
  880. * @returns {Number} The adjusted value.
  881. */
  882. function decimalAdjust(type, value, exp) {
  883. // If the exp is undefined or zero...
  884. if (typeof exp === 'undefined' || +exp === 0) {
  885. return Math[type](value);
  886. }
  887. value = +value;
  888. exp = +exp;
  889. // If the value is not a number or the exp is not an integer...
  890. if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
  891. return NaN;
  892. }
  893. // Shift
  894. value = value.toString().split('e');
  895. value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
  896. // Shift back
  897. value = value.toString().split('e');
  898. return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
  899. }
  900. // Decimal round
  901. if (!Math.round10) {
  902. Math.round10 = function(value, exp) {
  903. return decimalAdjust('round', value, exp);
  904. };
  905. }
  906. // Decimal floor
  907. if (!Math.floor10) {
  908. Math.floor10 = function(value, exp) {
  909. return decimalAdjust('floor', value, exp);
  910. };
  911. }
  912. // Decimal ceil
  913. if (!Math.ceil10) {
  914. Math.ceil10 = function(value, exp) {
  915. return decimalAdjust('ceil', value, exp);
  916. };
  917. }
  918. })();
  919. // Another solution, easier, to build a javascript rounding function
  920. function dolroundjs(number, decimals) { return +(Math.round(number + "e+" + decimals) + "e-" + decimals); }
  921. /**
  922. * Function similar to PHP price()
  923. *
  924. * @param {number|string} amount The amount to show
  925. * @param {string} mode 'MT' or 'MU'
  926. * @return {string} The amount with digits
  927. */
  928. function pricejs(amount, mode) {
  929. var main_max_dec_shown = <?php echo (int) str_replace('.', '', $conf->global->MAIN_MAX_DECIMALS_SHOWN); ?>;
  930. var main_rounding_unit = <?php echo (int) $conf->global->MAIN_MAX_DECIMALS_UNIT; ?>;
  931. var main_rounding_tot = <?php echo (int) $conf->global->MAIN_MAX_DECIMALS_TOT; ?>;
  932. if (mode == 'MU') return amount.toFixed(main_rounding_unit);
  933. if (mode == 'MT') return amount.toFixed(main_rounding_tot);
  934. return 'Bad value for parameter mode';
  935. }
  936. /**
  937. * Function similar to PHP price2num()
  938. *
  939. * @param {number|string} amount The amount to convert/clean
  940. * @return {string} The amount in universal numeric format (Example: '99.99999')
  941. * @todo Implement rounding parameter
  942. */
  943. function price2numjs(amount) {
  944. if (amount == '') return '';
  945. <?php
  946. $dec = ',';
  947. $thousand = ' ';
  948. if ($langs->transnoentitiesnoconv("SeparatorDecimal") != "SeparatorDecimal") {
  949. $dec = $langs->transnoentitiesnoconv("SeparatorDecimal");
  950. }
  951. if ($langs->transnoentitiesnoconv("SeparatorThousand") != "SeparatorThousand") {
  952. $thousand = $langs->transnoentitiesnoconv("SeparatorThousand");
  953. }
  954. if ($thousand == 'Space') $thousand=' ';
  955. print "var dec='" . dol_escape_js($dec) . "'; var thousand='" . dol_escape_js($thousand) . "';\n"; // Set var in javascript
  956. ?>
  957. var main_max_dec_shown = <?php echo (int) str_replace('.', '', $conf->global->MAIN_MAX_DECIMALS_SHOWN); ?>;
  958. var main_rounding_unit = <?php echo (int) $conf->global->MAIN_MAX_DECIMALS_UNIT; ?>;
  959. var main_rounding_tot = <?php echo (int) $conf->global->MAIN_MAX_DECIMALS_TOT; ?>;
  960. var amount = amount.toString();
  961. // rounding for unit price
  962. var rounding = main_rounding_unit;
  963. var pos = amount.indexOf(dec);
  964. var decpart = '';
  965. if (pos >= 0) decpart = amount.substr(pos + 1).replace('/0+$/i', ''); // Remove 0 for decimal part
  966. var nbdec = decpart.length;
  967. if (nbdec > rounding) rounding = nbdec;
  968. // If rounding higher than max shown
  969. if (rounding > main_max_dec_shown) rounding = main_max_dec_shown;
  970. if (thousand != ',' && thousand != '.') amount = amount.replace(',', '.');
  971. amount = amount.replace(' ', ''); // To avoid spaces
  972. amount = amount.replace(thousand, ''); // Replace of thousand before replace of dec to avoid pb if thousand is .
  973. amount = amount.replace(dec, '.');
  974. //console.log("amount before="+amount+" rouding="+rounding)
  975. var res = Math.round10(amount, - rounding);
  976. // Other solution is
  977. // var res = dolroundjs(amount, rounding)
  978. console.log("res="+res)
  979. return res;
  980. }
  981. <?php
  982. if (empty($conf->global->MAIN_DISABLE_JQUERY_JNOTIFY) && ! defined('DISABLE_JQUERY_JNOTIFY')) {
  983. ?>
  984. // Defined properties for JNotify
  985. $(document).ready(function() {
  986. if (typeof $.jnotify == 'function')
  987. {
  988. $.jnotify.setup({
  989. delay: 3000 // the default time to show each notification (in milliseconds)
  990. , sticky: false // determines if the message should be considered "sticky" (user must manually close notification)
  991. , closeLabel: "&times;" // the HTML to use for the "Close" link
  992. , showClose: true // determines if the "Close" link should be shown if notification is also sticky
  993. , fadeSpeed: 1000 // the speed to fade messages out (in milliseconds)
  994. , slideSpeed: 250 // the speed used to slide messages out (in milliseconds)
  995. , classContainer: "jnotify-container"
  996. , classNotification: "jnotify-notification"
  997. , classBackground: "jnotify-background"
  998. , classClose: "jnotify-close"
  999. , classMessage: "jnotify-message"
  1000. , init: null // callback that occurs when the main jnotify container is created
  1001. , create: null // callback that occurs when when the note is created (occurs just before appearing in DOM)
  1002. , beforeRemove: null // callback that occurs when before the notification starts to fade away
  1003. });
  1004. }
  1005. });
  1006. <?php } ?>
  1007. // End of lib_head.js.php