dolibarr  21.0.0-alpha
lib_head.js.php
Go to the documentation of this file.
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  * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program. If not, see <https://www.gnu.org/licenses/>.
19  * or see https://www.gnu.org/
20  */
21 
28 if (!defined('NOREQUIRESOC')) {
29  define('NOREQUIRESOC', '1');
30 }
31 if (!defined('NOCSRFCHECK')) {
32  define('NOCSRFCHECK', 1);
33 }
34 if (!defined('NOTOKENRENEWAL')) {
35  define('NOTOKENRENEWAL', 1);
36 }
37 if (!defined('NOLOGIN')) {
38  define('NOLOGIN', 1);
39 }
40 if (!defined('NOREQUIREMENU')) {
41  define('NOREQUIREMENU', 1);
42 }
43 if (!defined('NOREQUIREHTML')) {
44  define('NOREQUIREHTML', 1);
45 }
46 if (!defined('NOREQUIREAJAX')) {
47  define('NOREQUIREAJAX', '1');
48 }
49 
50 session_cache_limiter('public');
51 
52 require_once '../../main.inc.php';
53 
54 
55 /*
56  * View
57  */
58 
59 // Define javascript type
60 top_httphead('text/javascript; charset=UTF-8');
61 // Important: Following code is to avoid page request by browser and PHP CPU at each Dolibarr page access.
62 if (empty($dolibarr_nocache)) {
63  header('Cache-Control: max-age=10800, public, must-revalidate');
64 } else {
65  header('Cache-Control: no-cache');
66 }
67 
68 
69 
70 // Define tradMonths javascript array (we define this in datepicker AND in parent page to avoid errors with IE8)
71 $tradMonths = array(
72 dol_escape_js($langs->transnoentitiesnoconv("Month01")),
73 dol_escape_js($langs->transnoentitiesnoconv("Month02")),
74 dol_escape_js($langs->transnoentitiesnoconv("Month03")),
75 dol_escape_js($langs->transnoentitiesnoconv("Month04")),
76 dol_escape_js($langs->transnoentitiesnoconv("Month05")),
77 dol_escape_js($langs->transnoentitiesnoconv("Month06")),
78 dol_escape_js($langs->transnoentitiesnoconv("Month07")),
79 dol_escape_js($langs->transnoentitiesnoconv("Month08")),
80 dol_escape_js($langs->transnoentitiesnoconv("Month09")),
81 dol_escape_js($langs->transnoentitiesnoconv("Month10")),
82 dol_escape_js($langs->transnoentitiesnoconv("Month11")),
83 dol_escape_js($langs->transnoentitiesnoconv("Month12"))
84 );
85 
86 $tradMonthsShort = array(
87 $langs->trans("MonthShort01"),
88 $langs->trans("MonthShort02"),
89 $langs->trans("MonthShort03"),
90 $langs->trans("MonthShort04"),
91 $langs->trans("MonthShort05"),
92 $langs->trans("MonthShort06"),
93 $langs->trans("MonthShort07"),
94 $langs->trans("MonthShort08"),
95 $langs->trans("MonthShort09"),
96 $langs->trans("MonthShort10"),
97 $langs->trans("MonthShort11"),
98 $langs->trans("MonthShort12")
99 );
100 
101 $tradDays = array(
102 $langs->trans("Sunday"),
103 $langs->trans("Monday"),
104 $langs->trans("Tuesday"),
105 $langs->trans("Wednesday"),
106 $langs->trans("Thursday"),
107 $langs->trans("Friday"),
108 $langs->trans("Saturday")
109 );
110 
111 $tradDaysShort = array(
112 $langs->trans("ShortSunday"),
113 $langs->trans("ShortMonday"),
114 $langs->trans("ShortTuesday"),
115 $langs->trans("ShortWednesday"),
116 $langs->trans("ShortThursday"),
117 $langs->trans("ShortFriday"),
118 $langs->trans("ShortSaturday")
119 );
120 
121 $tradDaysMin = array(
122 $langs->trans("SundayMin"),
123 $langs->trans("MondayMin"),
124 $langs->trans("TuesdayMin"),
125 $langs->trans("WednesdayMin"),
126 $langs->trans("ThursdayMin"),
127 $langs->trans("FridayMin"),
128 $langs->trans("SaturdayMin")
129 );
130 
131 
132 $dec = ',';
133 $thousand = ' ';
134 if ($langs->transnoentitiesnoconv("SeparatorDecimal") != "SeparatorDecimal") {
135  $dec = $langs->transnoentitiesnoconv("SeparatorDecimal");
136 }
137 if ($langs->transnoentitiesnoconv("SeparatorThousand") != "SeparatorThousand") {
138  $thousand = $langs->transnoentitiesnoconv("SeparatorThousand");
139 }
140 if ($thousand == 'Space') {
141  $thousand = ' ';
142 }
143 
144 ?>
145 // Javascript libraries for Dolibarr ERP CRM (https://www.dolibarr.org)
146 
147 // For jQuery date picker
148 var tradMonths = <?php echo json_encode($tradMonths) ?>;
149 var tradMonthsShort = <?php echo json_encode($tradMonthsShort) ?>;
150 var tradDays = <?php echo json_encode($tradDays) ?>;
151 var tradDaysShort = <?php echo json_encode($tradDaysShort) ?>;
152 var tradDaysMin = <?php echo json_encode($tradDaysMin) ?>;
153 var currencyCache = <?php echo json_encode($langs->cache_currencies) ?>;
154 
155 // For JQuery date picker
156 $(document).ready(function() {
157  $.datepicker.setDefaults({
158  autoSize: true,
159  changeMonth: true,
160  changeYear: true,
161  altField: '#timestamp',
162  altFormat: '@' // Gives a timestamp dateformat
163  });
164 });
165 
166 jQuery(function($){
167  $.datepicker.regional['<?php echo $langs->defaultlang ?>'] = {
168  closeText: '<?php echo $langs->trans("Close2") ?>',
169  prevText: '<?php echo $langs->trans("Previous") ?>',
170  nextText: '<?php echo $langs->trans("Next") ?>',
171  currentText: '<?php echo $langs->trans("Now") ?>',
172  monthNames: tradMonths,
173  monthNamesShort: tradMonthsShort,
174  dayNames: tradDays,
175  dayNamesShort: tradDaysShort,
176  dayNamesMin: tradDaysMin,
177  weekHeader: '<?php echo $langs->trans("Week"); ?>',
178  dateFormat: '<?php echo $langs->trans("FormatDateShortJQuery"); ?>', /* Note dd/mm/yy means year on 4 digit in jquery format */
179  firstDay: <?php echo(isset($conf->global->MAIN_START_WEEK) ? $conf->global->MAIN_START_WEEK : '1'); ?>,
180  isRTL: <?php echo($langs->trans("DIRECTION") == 'rtl' ? 'true' : 'false'); ?>,
181  showMonthAfterYear: false, /* TODO add specific to country */
182  yearSuffix: '' /* TODO add specific to country */
183  };
184  $.datepicker.setDefaults($.datepicker.regional['<?php echo $langs->defaultlang ?>']);
185 });
186 
187 
188 
193 var select2arrayoflanguage = {
194  matches: function (matches) { return matches + " <?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2ResultFoundUseArrows")); ?>"; },
195  noResults: function () { return "<?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2NotFound")); ?>"; },
196  inputTooShort: function (input) {
197  var n = input.minimum;
198  /*console.log(input); console.log(input.minimum);*/
199  if (n > 1) return "<?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2Enter")); ?> " + n + " <?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2MoreCharacters")); ?>";
200  else return "<?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2Enter")); ?> " + n + " <?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2MoreCharacter")); ?>"
201  },
202  loadMore: function (pageNumber) { return "<?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2LoadingMoreResults")); ?>"; },
203  searching: function () { return "<?php echo dol_escape_js($langs->transnoentitiesnoconv("Select2SearchInProgress")); ?>"; }
204 };
205 
206 
211 // Returns an object given an id
212 function getObjectFromID(id){
213  var theObject;
214  if(document.getElementById)
215  theObject=document.getElementById(id);
216  else
217  theObject=document.all[id];
218  return theObject;
219 }
220 
221 // Called after selection of a date to save details into detailed fields
222 function dpChangeDay(dateFieldID, format)
223 {
224  //showDP.datefieldID=dateFieldID;
225  console.log("Call dpChangeDay, we save date into detailed fields from format = "+format);
226 
227  var thefield=getObjectFromID(dateFieldID);
228  var thefieldday=getObjectFromID(dateFieldID+"day");
229  var thefieldmonth=getObjectFromID(dateFieldID+"month");
230  var thefieldyear=getObjectFromID(dateFieldID+"year");
231 
232  var date=getDateFromFormat(thefield.value, format);
233  //console.log(date);
234  if (date)
235  {
236  thefieldday.value=date.getDate();
237  if(thefieldday.onchange) thefieldday.onchange.call(thefieldday);
238  thefieldmonth.value=date.getMonth()+1;
239  if(thefieldmonth.onchange) thefieldmonth.onchange.call(thefieldmonth);
240  thefieldyear.value=date.getFullYear();
241  if(thefieldyear.onchange) thefieldyear.onchange.call(thefieldyear);
242  }
243  else
244  {
245  thefieldday.value='';
246  if(thefieldday.onchange) thefieldday.onchange.call(thefieldday);
247  thefieldmonth.value='';
248  if(thefieldmonth.onchange) thefieldmonth.onchange.call(thefieldmonth);
249  thefieldyear.value='';
250  if(thefieldyear.onchange) thefieldyear.onchange.call(thefieldyear);
251  }
252 }
253 
254 /*
255  * =================================================================
256  * Function: formatDate(javascript object Date(), format)
257  * Purpose: Returns a date in the output format specified. The format string can use the following tags:
258  * Year | yyyy (4 digits), yy (2 digits)
259  * Month | MM (2 digits)
260  * Day of Month | dd (2 digits)
261  * Hour (1-12) | hh (2 digits) Hour (0-23) | HH (2 digits)
262  * Minute | mm (2 digits)
263  * Second | ss (2 digits)
264  * Author: Laurent Destailleur Author: Matelli (see http://matelli.fr/showcases/patchs-dolibarr/update-date-input-in-action-form.html)
265  * Licence: GPL
266  * ==================================================================
267  */
268 function formatDate(date,format)
269 {
270  // alert('formatDate date='+date+' format='+format);
271 
272  // Force parameters en chaine
273  format=format+"";
274 
275  var result="";
276 
277  var year=date.getYear()+""; if (year.length < 4) { year=""+(year-0+2000); } /* #28334 */
278  var month=date.getMonth()+1;
279  var day=date.getDate();
280  var hour=date.getHours();
281  var minute=date.getMinutes();
282  var seconde=date.getSeconds();
283 
284  var i=0;
285  while (i < format.length)
286  {
287  c=format.charAt(i); // Recupere char du format
288  var substr = '';
289  j=i;
290  while ((format.charAt(j)==c) && (j < format.length)) // Recupere char successif identiques
291  {
292  substr += format.charAt(j++);
293  }
294 
295  // alert('substr='+substr);
296  if (substr == 'yyyy') { result=result+year; }
297  else if (substr == 'yy') { result=result+year.substring(2,4); }
298  else if (substr == 'M') { result=result+month; }
299  else if (substr == 'MM') { result=result+(month<1||month>9?"":"0")+month; }
300  else if (substr == 'd') { result=result+day; }
301  else if (substr == 'dd') { result=result+(day<1||day>9?"":"0")+day; }
302  else if (substr == 'hh') { if (hour > 12) hour-=12; result=result+(hour<0||hour>9?"":"0")+hour; }
303  else if (substr == 'HH') { result=result+(hour<0||hour>9?"":"0")+hour; }
304  else if (substr == 'mm') { result=result+(minute<0||minute>9?"":"0")+minute; }
305  else if (substr == 'ss') { result=result+(seconde<0||seconde>9?"":"0")+seconde; }
306  else { result=result+substr; }
307 
308  i+=substr.length;
309  }
310 
311  // alert(result);
312  return result;
313 }
314 
315 
316 /*
317  * =================================================================
318  * Function: getDateFromFormat(date_string, format_string)
319  * Purpose: This function takes a date string and a format string.
320  * It parses the date string with format and it
321  * returns the date as a javascript Date() object. If date does not match
322  * format, it returns 0. The format string can use the following tags:
323  * Field | Tags
324  * -------------+-----------------------------------
325  * Year | yyyy (4 digits), yy (2 digits)
326  * Month | MM (2 digits)
327  * Day of Month | dd (2 digits)
328  * Hour (1-12) | hh (2 digits)
329  * Hour (0-23) | HH (2 digits)
330  * Minute | mm (2 digits)
331  * Second | ss (2 digits)
332  * Author: Laurent Destailleur
333  * Licence: GPL
334  * ==================================================================
335  */
336 function getDateFromFormat(val,format)
337 {
338  // alert('getDateFromFormat val='+val+' format='+format);
339 
340  // Force parameters en chaine
341  val=val+"";
342  format=format+"";
343 
344  if (val == '') return 0;
345 
346  var now=new Date();
347  var year=now.getYear(); if (year.length < 4) { year=""+(year-0+2000); } /* #28334 */
348  var month=now.getMonth()+1;
349  var day=now.getDate();
350  var hour=now.getHours();
351  var minute=now.getMinutes();
352  var seconde=now.getSeconds();
353 
354  var i=0;
355  var d=0; // -d- follows the date string while -i- follows the format
356  // string
357 
358  while (i < format.length)
359  {
360  c=format.charAt(i); // Recupere char du format
361  substr="";
362  j=i;
363  while ((format.charAt(j)==c) && (j < format.length)) // Recupere char
364  // successif
365  // identiques
366  {
367  substr += format.charAt(j++);
368  }
369 
370  // alert('substr='+substr);
371  if (substr == "yyyy") year=getIntegerInString(val,d,4,4);
372  if (substr == "yy") year=""+(getIntegerInString(val,d,2,2)-0+2000); /* #28334 */
373  if (substr == "MM" ||substr == "M")
374  {
375  month=getIntegerInString(val,d,1,2);
376  if (month) d -= 2- month.length;
377  }
378  if (substr == "dd")
379  {
380  day=getIntegerInString(val,d,1,2);
381  if (day) d -= 2- day.length;
382  }
383  if (substr == "HH" ||substr == "hh" )
384  {
385  hour=getIntegerInString(val,d,1,2);
386  if (dhouray) d -= 2- hour.length;
387  }
388  if (substr == "mm"){
389  minute=getIntegerInString(val,d,1,2);
390  if (minute) d -= 2- minute.length;
391  }
392  if (substr == "ss")
393  {
394  seconde=getIntegerInString(val,d,1,2);
395  if (seconde) d -= 2- seconde.length;
396  }
397 
398  i+=substr.length;
399  d+=substr.length;
400  }
401 
402  // Check if format param are ok
403  if (year==null||year<1) { return 0; }
404  if (month==null||(month<1)||(month>12)) { return 0; }
405  if (day==null||(day<1)||(day>31)) { return 0; }
406  if (hour==null||(hour<0)||(hour>24)) { return 0; }
407  if (minute==null||(minute<0)||(minute>60)) { return 0; }
408  if (seconde==null||(seconde<0)||(seconde>60)) { return 0; }
409 
410  // alert(year+' '+month+' '+day+' '+hour+' '+minute+' '+seconde);
411  return new Date(year,month-1,day,hour,minute,seconde);
412 }
413 
414 /*
415  * =================================================================
416  * Function: stringIsInteger(string)
417  * Purpose: Return true if string is an integer
418  * ==================================================================
419  */
420 function stringIsInteger(str)
421 {
422  var digits="1234567890";
423  for (var i=0; i < str.length; i++)
424  {
425  if (digits.indexOf(str.charAt(i))==-1)
426  {
427  return false;
428  }
429  }
430  return true;
431 }
432 
433 /*
434  * =================================================================
435  * Function: getIntegerInString(string,pos,minlength,maxlength)
436  * Purpose: Return part of string from position i that is integer
437  * ==================================================================
438  */
439 function getIntegerInString(str,i,minlength,maxlength)
440 {
441  for (var x=maxlength; x>=minlength; x--)
442  {
443  var substr=str.substring(i,i+x);
444  if (substr.length < minlength) { return null; }
445  if (stringIsInteger(substr)) { return substr; }
446  }
447  return null;
448 }
449 
450 
451 /*
452  * =================================================================
453  * Purpose: Clean string to have it url encoded
454  * Input: s
455  * Author: Laurent Destailleur
456  * Licence: GPL
457  * ==================================================================
458  */
459 function urlencode(s) {
460  var news = s;
461  news = news.replace(/\+/gi,'%2B');
462  news = news.replace(/&/gi,'%26');
463  return news;
464 }
465 
466 /*
467  * =================================================================
468  * Purpose: Clean string to get a HTML coded string.
469  * Input: s
470  * Author: Laurent Destailleur
471  * Licence: GPL
472  * ==================================================================
473  */
474 function htmlEntityDecodeJs(inp){
475  var replacements = {'&lt;':'<','&gt;':'>','&sol;':'/','&quot;':'"','&apos;':'\'','&amp;':'&','&nbsp;':' '};
476  if (inp) {
477  for(var r in replacements){
478  inp = inp.replace(new RegExp(r,'g'),replacements[r]);
479  }
480  return inp.replace(/&#(\d+);/g, function(match, dec) {
481  return String.fromCharCode(dec);
482  });
483  } else {
484  return '';
485  }
486 }
487 
488 
489 /*
490  * =================================================================
491  * Purpose: Applique un delai avant execution. Used for autocompletion of companies.
492  * Input: funct, delay
493  * Author: Regis Houssin
494  * Licence: GPL
495  * ==================================================================
496  */
497  function ac_delay(funct,delay) {
498  // delay before start of action
499  setTimeout(funct,delay);
500 }
501 
502 
503 /*
504  * =================================================================
505  * Purpose:
506  * Clean values of a "Sortable.serialize". Used by drag and drop.
507  * Input: expr
508  * Author: Regis Houssin
509  * Licence: GPL
510  * ==================================================================
511  */
512 function cleanSerialize(expr) {
513  if (typeof(expr) != 'string') {
514  return '';
515  }
516  var reg = new RegExp("(&)", "g");
517  var reg2 = new RegExp("[^A-Z0-9,]", "g");
518  var liste1 = expr.replace(reg, ",");
519  return liste1.replace(reg2, "");
520 }
521 
522 
523 /*
524  * =================================================================
525  * Purpose: Display a temporary message in input text fields (For showing help message on
526  * input field).
527  * Input: fieldId
528  * Input: message
529  * Author: Regis Houssin
530  * Licence: GPL
531  * ==================================================================
532  */
533 function displayMessage(fieldId,message) {
534  var textbox = document.getElementById(fieldId);
535  if (textbox.value == '') {
536  textbox.style.color = 'grey';
537  textbox.value = message;
538  }
539 }
540 
541 /*
542  * =================================================================
543  * Purpose: Hide a temporary message in input text fields (For showing help message on
544  * input field).
545  * Input: fiedId
546  * Input: message
547  * Author: Regis Houssin
548  * Licence: GPL
549  * ==================================================================
550  */
551 function hideMessage(fieldId,message) {
552  var textbox = document.getElementById(fieldId);
553  textbox.style.color = 'black';
554  if (textbox.value == message) textbox.value = '';
555 }
556 
557 
558 /*
559  * Used by button to set on/off.
560  * Call url then make complementary action (like show/hide, enable/disable or set another option).
561  *
562  * @param string url Url (warning: as any url called in ajax mode, the url called here must not renew the token)
563  * @param string code Code
564  * @param string input Array of complementary actions to do if success
565  * @param int entity Entity
566  * @param int strict Strict (0=?, 1=?)
567  * @param int forcereload Force reload
568  * @param int userid User id
569  * @param int value Value to set
570  * @param string token Token
571  * @return boolean
572  */
573 function setConstant(url, code, input, entity, strict, forcereload, userid, token, value) {
574  var saved_url = url; /* avoid undefined url */
575  $.post( url, {
576  action: "set",
577  name: code,
578  entity: entity,
579  token: token,
580  value: value
581  },
582  function() { /* handler for success of post */
583  console.log("Ajax url request to set constant is a success. Make complementary actions and then forcereload="+forcereload+" value="+value);
584  if (value == 0) {
585  $("#set_" + code).show();
586  $("#del_" + code).hide();
587  } else {
588  $("#set_" + code).hide();
589  $("#del_" + code).show();
590  }
591  $.each(input, function(type, data) {
592  // Enable another element
593  if (type == "disabled" && strict != 1) {
594  $.each(data, function(key, value) {
595  var newvalue=((value.search("^#") < 0 && value.search("^\.") < 0) ? "#" : "") + value;
596  $(newvalue).removeAttr("disabled");
597  if ($(newvalue).hasClass("butActionRefused") == true) {
598  $(newvalue).removeClass("butActionRefused");
599  $(newvalue).addClass("butAction");
600  }
601  });
602  } else if (type == "enabled") {
603  $.each(data, function(key, value) {
604  var newvalue=((value.search("^#") < 0 && value.search("^\.") < 0) ? "#" : "") + value;
605  if (strict == 1)
606  $(newvalue).removeAttr("disabled");
607  else
608  $(newvalue).attr("disabled", true);
609  if ($(newvalue).hasClass("butAction") == true) {
610  $(newvalue).removeClass("butAction");
611  $(newvalue).addClass("butActionRefused");
612  }
613  });
614  // Show another element
615  } else if (type == "showhide" || type == "show") {
616  $.each(data, function(key, value) {
617  var newvalue=((value.search("^#") < 0 && value.search("^\.") < 0) ? "#" : "") + value;
618  $(newvalue).show();
619  });
620  // Set another constant
621  } else if (type == "set") {
622  $.each(data, function(key, value) {
623  $("#set_" + key).hide();
624  $("#del_" + key).show();
625  $.post( saved_url, {
626  action: "set",
627  name: key,
628  value: value,
629  entity: entity,
630  token: token
631  });
632  });
633  }
634  });
635  if (forcereload) {
636  var url = window.location.href;
637  if (url.indexOf('dol_resetcache') < 0) {
638  if (url.indexOf('?') > -1) {
639  url = url + "&dol_resetcache=1";
640  } else {
641  url = url + "?dol_resetcache=1";
642  }
643  }
644  var page_y = $(document).scrollTop();
645  url = url.replace(/page_y=\d+/g, '');
646  if (page_y > 0) {
647  if (url.indexOf('?') > -1) {
648  url = url + "&page_y="+page_y;
649  } else {
650  url = url + "?page_y="+page_y;
651  }
652  }
653  url = url.replace(/&&+/, '&');
654  console.log("url ro redirect = "+url);
655 
656  window.location.href = url;
657  //location.reload();
658  return false;
659  }
660  }).fail(function(error) { console.log("Error, we force reload"); location.reload(); }); /* When it fails, we always force reload to have setEventErrorMessages in session visible */
661 
662  return true;
663 }
664 
665 /*
666  * Used by button to set on/off
667  * Call url then make complementary action (like show/hide, enable/disable or set another option).
668  *
669  * @param {string} url Url (warning: as any url called in ajax mode, the url called here must not renew the token)
670  * @param {string} code Code
671  * @param {string} input Array of complementary actions to do if success
672  * @param {int} entity Entity
673  * @param {int} strict Strict
674  * @param {int} forcereload Force reload
675  * @param {int} userid User id
676  * @param {string} token Token
677  * @return boolean
678  */
679 function delConstant(url, code, input, entity, strict, forcereload, userid, token) {
680  var saved_url = url; /* avoid undefined url */
681  $.post( url, {
682  action: "del",
683  name: code,
684  entity: entity,
685  token: token
686  },
687  function() {
688  console.log("Ajax url request to delete constant is success. Make complementary actions and then forcereload="+forcereload);
689  $("#del_" + code).hide();
690  $("#set_" + code).show();
691  $.each(input, function(type, data) {
692  // Disable another element
693  if (type == "disabled") {
694  $.each(data, function(key, value) {
695  var newvalue=((value.search("^#") < 0 && value.search("^\.") < 0) ? "#" : "") + value;
696  $(newvalue).attr("disabled", true);
697  if ($(newvalue).hasClass("butAction") == true) {
698  $(newvalue).removeClass("butAction");
699  $(newvalue).addClass("butActionRefused");
700  }
701  });
702  } else if (type == "enabled" && strict != 1) {
703  $.each(data, function(key, value) {
704  var newvalue=((value.search("^#") < 0 && value.search("^\.") < 0) ? "#" : "") + value;
705  $(newvalue).removeAttr("disabled");
706  if ($(newvalue).hasClass("butActionRefused") == true) {
707  $(newvalue).removeClass("butActionRefused");
708  $(newvalue).addClass("butAction");
709  }
710  });
711  // Hide another element
712  } else if (type == "showhide" || type == "hide") {
713  $.each(data, function(key, value) {
714  var newvalue=((value.search("^#") < 0 && value.search("^\.") < 0) ? "#" : "") + value;
715  $(newvalue).hide();
716  });
717  // Delete another constant
718  } else if (type == "del") {
719  $.each(data, function(key, value) {
720  $("#del_" + value).hide();
721  $("#set_" + value).show();
722  $.post( saved_url, {
723  action: "del",
724  name: value,
725  entity: entity,
726  token: token
727  });
728  });
729  }
730  });
731  if (forcereload) {
732  var url = window.location.href;
733  if (url.indexOf('dol_resetcache') < 0) {
734  if (url.indexOf('?') > -1) {
735  url = url + "&dol_resetcache=1";
736  } else {
737  url = url + "?dol_resetcache=1";
738  }
739  }
740  var page_y = $(document).scrollTop();
741  url = url.replace(/page_y=\d+/g, '');
742  if (page_y > 0) {
743  if (url.indexOf('?') > -1) {
744  url = url + "&page_y="+page_y;
745  } else {
746  url = url + "?page_y="+page_y;
747  }
748  }
749  url = url.replace(/&&+/, '&');
750  console.log("url ro redirect = "+url);
751 
752  window.location.href = url;
753  //location.reload();
754  return false;
755  }
756  }).fail(function(error) { console.log("Error, we force reload"); location.reload(); }); /* When it fails, we always force reload to have setEventErrorMessages in session visible */
757 
758  return true;
759 }
760 
761 /*
762  * Call the setConstant or delConstant but with a confirmation before.
763  * Used by button to set on/off.
764  *
765  * @param string action Action
766  * @param string url Url
767  * @param string code Code
768  * @param string input Array of complementary actions to do if success
769  * @param string box Box
770  * @param int entity Entity
771  * @param int yesButton yesButton
772  * @param int noButton noButton
773  * @param int strict Strict
774  * @param int userid User id
775  * @param string token Token
776  * @return boolean
777  */
778 function confirmConstantAction(action, url, code, input, box, entity, yesButton, noButton, strict, userid, token) {
779  var boxConfirm = box;
780  $("#confirm_" + code)
781  .attr("title", boxConfirm.title)
782  .html(boxConfirm.content)
783  .dialog({
784  resizable: false,
785  height: 170,
786  width: 500,
787  modal: true,
788  buttons: [
789  {
790  id : 'yesButton_' + code,
791  text : yesButton,
792  click : function() {
793  if (action == "set") {
794  setConstant(url, code, input, entity, strict, 0, userid, token, 1);
795  } else if (action == "del") {
796  delConstant(url, code, input, entity, strict, 0, userid, token);
797  }
798  // Close dialog
799  $(this).dialog("close");
800  // Execute another method
801  if (boxConfirm.method) {
802  var fnName = boxConfirm.method;
803  if (window.hasOwnProperty(fnName)) {
804  window[fnName]();
805  }
806  }
807  }
808  },
809  {
810  id : 'noButton_' + code,
811  text : noButton,
812  click : function() {
813  $(this).dialog("close");
814  }
815  }
816  ]
817  });
818  // For information dialog box only, hide the noButton
819  if (boxConfirm.info) {
820  $("#noButton_" + code).button().hide();
821  }
822 
823  return true;
824 }
825 
826 
827 /*
828  * =================================================================
829  * This is to allow to transform all select box into ajax autocomplete box
830  * with just one line:
831  * $(function() { $( "#idofmylist" ).combobox(); });
832  * Do not use it on large combo boxes
833  * =================================================================
834  */
835 (function( $ ) {
836  $.widget( "ui.combobox", {
837  options: {
838  minLengthToAutocomplete: 0
839  },
840  _create: function() {
841  var savMinLengthToAutocomplete = this.options.minLengthToAutocomplete;
842  var self = this,
843  select = this.element.hide(),
844  selected = select.children( ":selected" ),
845  value = selected.val() ? selected.text() : "";
846  var input = this.input = $( "<input>" )
847  .insertAfter( select )
848  .val( value )
849  .attr('id', 'inputautocomplete'+select.attr('id'))
850  .autocomplete({
851  delay: 0,
852  minLength: this.options.minLengthToAutocomplete,
853  source: function( request, response ) {
854  var matcher = new RegExp( $.ui.autocomplete.escapeRegex(request.term), "i" );
855  response( select.children( "option:enabled" ).map(function() {
856  var text = $( this ).text();
857  if ( this.value && ( !request.term || matcher.test(text) ) )
858  return {
859  label: text.replace(
860  new RegExp(
861  "(?![^&;]+;)(?!<[^<>]*)(" +
862  $.ui.autocomplete.escapeRegex(request.term) +
863  ")(?![^<>]*>)(?![^&;]+;)", "gi"
864  ), "<strong>$1</strong>" ),
865  value: text,
866  option: this
867  };
868  }) );
869  },
870  select: function( event, ui ) {
871  ui.item.option.selected = true;
872  self._trigger( "selected", event, {
873  item: ui.item.option
874  });
875  },
876  change: function( event, ui ) {
877  if ( !ui.item ) {
878  var matcher = new RegExp( "^" + $.ui.autocomplete.escapeRegex( $(this).val() ) + "$", "i" ),
879  valid = false;
880  select.children( "option" ).each(function() {
881  if ( $( this ).text().match( matcher ) ) {
882  this.selected = valid = true;
883  return false;
884  }
885  });
886  if ( !valid ) {
887  // remove invalid value, as it didn't match anything
888  $( this ).val( "" );
889  select.val( "" );
890  input.data("ui-autocomplete").term = "";
891  return false;
892  }
893  }
894  }
895  })
896  .addClass( "ui-widget ui-widget-content ui-corner-left dolibarrcombobox" );
897 
898  input.data("ui-autocomplete")._renderItem = function( ul, item ) {
899  return $("<li>")
900  .data( "ui-autocomplete-item", item ) // jQuery UI > 1.10.0
901  .append( "<a>" + item.label + "</a>" )
902  .appendTo( ul );
903  };
904 
905  this.button = $( "<button type=\'button\'>&nbsp;</button>" )
906  .attr( "tabIndex", -1 )
907  .attr( "title", "Show All Items" )
908  .insertAfter( input )
909  .button({
910  icons: {
911  primary: "ui-icon-triangle-1-s"
912  },
913  text: false
914  })
915  .removeClass( "ui-corner-all" )
916  .addClass( "ui-corner-right ui-button-icon" )
917  .click(function() {
918  // close if already visible
919  if ( input.autocomplete( "widget" ).is( ":visible" ) ) {
920  input.autocomplete( "close" );
921  return;
922  }
923 
924  // pass empty string as value to search for, displaying all results
925  input.autocomplete({ minLength: 0 });
926  input.autocomplete( "search", "" );
927  input.autocomplete({ minLength: savMinLengthToAutocomplete });
928  input.focus();
929  });
930  },
931 
932  destroy: function() {
933  this.input.remove();
934  this.button.remove();
935  this.element.show();
936  $.Widget.prototype.destroy.call( this );
937  }
938  });
939 })( jQuery );
940 
941 
942 
949 function copyToClipboard(text,text2)
950 {
951  text = text.replace(/<br>/g,"\n");
952  var newElem = '<textarea id="coordsforpopup" style="border: none; width: 90%; height: 120px;">'+text+'</textarea><br><br>'+text2;
953  /* alert(newElem); */
954  $("#dialogforpopup").html(newElem);
955  $("#dialogforpopup").dialog();
956  $("#coordsforpopup").select();
957 
958  return false;
959 }
960 
961 
970 function newpopup(url, title) {
971  var argv = newpopup.arguments;
972  var argc = newpopup.arguments.length;
973  var tmp = url;
974  console.log("newpopup "+argv[2]+" "+argv[3]);
975  var l = (argc > 2) ? argv[2] : 600;
976  var h = (argc > 3) ? argv[3] : 400;
977  var left = (screen.width - l)/2;
978  var top = (screen.height - h)/2;
979  var wfeatures = "directories=0,menubar=0,status=0,resizable=0,scrollbars=1,toolbar=0,width=" + l +",height=" + h + ",left=" + left + ",top=" + top;
980  fen=window.open(tmp,title,wfeatures);
981 
982  return false;
983 }
984 
995 function document_preview(file, type, title)
996 {
997  var ValidImageTypes = ["image/gif", "image/jpeg", "image/png", "image/webp"];
998  var showOriginalSizeButton = false;
999 
1000  console.log("document_preview A click was done: file="+file+", type="+type+", title="+title);
1001 
1002  if ($.inArray(type, ValidImageTypes) < 0) {
1003  /* Not an image */
1004  var width='85%';
1005  var object_width='100%';
1006  var height = ($( window ).height() - 60) * 0.90;
1007  var object_height='98%';
1008 
1009  show_preview('notimage');
1010 
1011  } else {
1012  /* This is an image */
1013  var object_width=0;
1014  var object_height=0;
1015 
1016  var img = new Image();
1017 
1018  img.onload = function() {
1019  object_width = this.width;
1020  object_height = this.height;
1021 
1022  width = $( window ).width()*0.90;
1023  console.log("object_width="+object_width+" window width="+width);
1024  if(object_width < width){
1025  console.log("Object width is small, we set width of popup according to image width.");
1026  width = object_width + 30
1027  }
1028  height = $( window ).height()*0.85;
1029  console.log("object_height="+object_height+" window height="+height);
1030  if(object_height < height){
1031  console.log("Object height is small, we set height of popup according to image height.");
1032  height = object_height + 80
1033  }
1034  else
1035  {
1036  showOriginalSizeButton = true;
1037  }
1038 
1039  show_preview('image');
1040 
1041  };
1042  img.src = file;
1043 
1044  }
1045 
1046  function show_preview(mode) {
1047  /* console.log("mode="+mode+" file="+file+" type="+type+" width="+width+" height="+height); */
1048  var newElem = '<object name="objectpreview" data="'+file+'" type="'+type+'" width="'+object_width+'" height="'+object_height+'" param="noparam"></object>';
1049 
1050  optionsbuttons = {}
1051  if (mode == 'image' && showOriginalSizeButton)
1052  {
1053  var curRot = 0;
1054  optionsbuttons = {
1055  "<?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" }); },
1056  "<?php echo dol_escape_js($langs->transnoentitiesnoconv("RotateImage")); ?>": function() { curRot += 90; jQuery(".ui-dialog-content.ui-widget-content > object").css("transform","rotate(" + curRot + "deg)"); },
1057  "<?php echo dol_escape_js($langs->transnoentitiesnoconv("CloseWindow")); ?>": function() { $( this ).dialog( "close" ); }
1058  };
1059  }
1060 
1061  $("#dialogforpopup").html(newElem);
1062 
1063  $("#dialogforpopup").dialog({
1064  closeOnEscape: true,
1065  resizable: true,
1066  width: width,
1067  height: height,
1068  modal: true,
1069  title: title,
1070  buttons: optionsbuttons
1071  });
1072 
1073  if (showOriginalSizeButton)
1074  {
1075  jQuery(".ui-dialog-content.ui-widget-content > object").css({ "max-height": "100%", "width": "auto", "margin-left": "auto", "margin-right": "auto", "display": "block" });
1076  }
1077  }
1078 }
1079 
1080 /*
1081  * Provide a function to get an URL GET parameter in javascript
1082  *
1083  * @param name Name of parameter
1084  * @param valueifnotfound Value if not found
1085  * @return string Value
1086  */
1087 function getParameterByName(name, valueifnotfound)
1088 {
1089  name = name.replace(/[\[]/, "\\[").replace(/[\]]/, "\\]");
1090  var regex = new RegExp("[\\?&]" + name + "=([^&#]*)"),
1091  results = regex.exec(location.search);
1092  return results === null ? valueifnotfound : decodeURIComponent(results[1].replace(/\+/g, " "));
1093 }
1094 
1095 
1096 // Code in the public domain from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
1097 (function() {
1106  function decimalAdjust(type, value, exp) {
1107  // If the exp is undefined or zero...
1108  if (typeof exp === 'undefined' || +exp === 0) {
1109  return Math[type](value);
1110  }
1111  value = +value;
1112  exp = +exp;
1113  // If the value is not a number or the exp is not an integer...
1114  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
1115  return NaN;
1116  }
1117  // Shift
1118  value = value.toString().split('e');
1119  value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
1120  // Shift back
1121  value = value.toString().split('e');
1122  return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
1123  }
1124 
1125  // Decimal round
1126  if (!Math.round10) {
1127  Math.round10 = function(value, exp) {
1128  return decimalAdjust('round', value, exp);
1129  };
1130  }
1131  // Decimal floor
1132  if (!Math.floor10) {
1133  Math.floor10 = function(value, exp) {
1134  return decimalAdjust('floor', value, exp);
1135  };
1136  }
1137  // Decimal ceil
1138  if (!Math.ceil10) {
1139  Math.ceil10 = function(value, exp) {
1140  return decimalAdjust('ceil', value, exp);
1141  };
1142  }
1143 })();
1144 
1145 // Another solution, easier, to build a javascript rounding function
1146 function dolroundjs(number, decimals) { return +(Math.round(number + "e+" + decimals) + "e-" + decimals); }
1147 
1165 function pricejs(amount, mode = 'MT', currency_code = '', force_locale = '') {
1166  var main_max_dec_shown = <?php echo (int) str_replace('.', '', getDolGlobalString('MAIN_MAX_DECIMALS_SHOWN')); ?>;
1167  var main_rounding_unit = <?php echo (int) getDolGlobalInt('MAIN_MAX_DECIMALS_UNIT'); ?>;
1168  var main_rounding_tot = <?php echo (int) getDolGlobalInt('MAIN_MAX_DECIMALS_TOT'); ?>;
1169  var main_decimal_separator = <?php echo json_encode($dec) ?>;
1170  var main_thousand_separator = <?php echo json_encode($thousand) ?>;
1171  var locale_code = force_locale || <?php echo json_encode($langs->defaultlang) ?>;
1172  var amountAsLocalizedString;
1173  var useIntl = Boolean(Intl && Intl.NumberFormat);
1174  var nDigits;
1175  if (currency_code === 'auto') currency_code = <?php echo json_encode($conf->currency) ?>;
1176 
1177  if (mode === 'MU') nDigits = main_rounding_unit;
1178  else if (mode === 'MT') nDigits = main_rounding_tot;
1179  else return 'Bad value for parameter mode';
1180 
1181  if (useIntl) {
1182  // simple version: let the browser decide how to format the number using the provided language / currency
1183  // parameters
1184  var formattingOptions = {
1185  minimumFractionDigits: nDigits,
1186  maximumFractionDigits: nDigits
1187  };
1188  if (currency_code) {
1189  formattingOptions['style'] = 'currency';
1190  formattingOptions['currency'] = currency_code;
1191  }
1192  return Intl.NumberFormat(locale_code.replace('_', '-'), formattingOptions).format(amount);
1193  }
1194 
1195  // No Intl -> attempt to format the number in a way similar to Dolibarr PHP's `price()` function
1196  amountAsLocalizedString = amount.toFixed(nDigits).replace(
1197  /((?!^)(?:\d{3})*)(?:\.(\d+))?$/,
1198  (fullMatch, digitsByThree, decimals) =>
1199  digitsByThree.replace(
1200  /\d{3}/g,
1201  (groupOfThree) => main_thousand_separator + groupOfThree
1202  ) + (decimals !== undefined ? main_decimal_separator + decimals : '')
1203  ).replace(/ /, ' ');
1204  if (!currency_code) return amountAsLocalizedString;
1205 
1206  // print with currency
1207  var currency_symbol = currency_code;
1208 
1209  // codes of languages / currencies where the symbol must be placed before the amount
1210  var currencyBeforeAmountCodes = {
1211  currency: ['AUD', 'CAD', 'CNY', 'COP', 'CLP', 'GBP', 'HKD', 'MXN', 'PEN', 'USD'],
1212  language: ['nl_NL']
1213  };
1214 
1215  if (currencyCache[currency_code]
1216  && currencyCache[currency_code]['unicode']
1217  && currencyCache[currency_code]['unicode'].length) {
1218  currency_symbol = currencyCache[currency_code]['unicode'].reduce(function (res, cur) {return res + cur}, '');
1219  }
1220 
1221  if (currencyBeforeAmountCodes.currency.indexOf(currency_code) >= 0
1222  || currencyBeforeAmountCodes.language.indexOf(locale_code)) {
1223  // if we use a language or a currency where the symbol is placed before the amount
1224  return currency_symbol + amountAsLocalizedString;
1225  }
1226 
1227  // by default: currency symbol after the amount
1228  return amountAsLocalizedString + ' ' + currency_symbol;
1229 }
1230 
1238 function price2numjs(amount) {
1239  if (amount == '') return '';
1240 
1241  var dec = <?php echo json_encode($dec) ?>;
1242  var thousand = <?php echo json_encode($thousand) ?>;
1243 
1244  var main_max_dec_shown = <?php echo (int) str_replace('.', '', getDolGlobalString('MAIN_MAX_DECIMALS_SHOWN')); ?>;
1245  var main_rounding_unit = <?php echo (int) getDolGlobalInt('MAIN_MAX_DECIMALS_UNIT'); ?>;
1246  var main_rounding_tot = <?php echo (int) getDolGlobalInt('MAIN_MAX_DECIMALS_TOT'); ?>;
1247 
1248  var amount = amount.toString();
1249 
1250  // rounding for unit price
1251  var rounding = main_rounding_unit;
1252  var pos = amount.indexOf(dec);
1253  var decpart = '';
1254  if (pos >= 0) {
1255  decpart = amount.substring(pos + 1).replace('/0+$/i', ''); // Remove 0 for decimal part
1256  }
1257  var nbdec = decpart.length;
1258  if (nbdec > rounding) {
1259  rounding = nbdec;
1260  }
1261  // If rounding higher than max shown
1262  if (rounding > main_max_dec_shown) rounding = main_max_dec_shown;
1263  if (thousand != ',' && thousand != '.') amount = amount.replace(',', '.');
1264  amount = amount.replace(' ', ''); // To avoid spaces
1265  amount = amount.replace(thousand, ''); // Replace of thousand before replace of dec to avoid pb if thousand is .
1266  amount = amount.replace(dec, '.');
1267 
1268  //console.log("amount before="+amount+" rounding="+rounding)
1269  var res = Math.round10(amount, - rounding);
1270  // Other solution is
1271  // var res = dolroundjs(amount, rounding)
1272 
1273  console.log("price2numjs text="+amount+" return="+res);
1274 
1275  return res;
1276 }
1277 
1278 
1279 <?php
1280 if (!getDolGlobalString('MAIN_DISABLE_JQUERY_JNOTIFY') && !defined('DISABLE_JQUERY_JNOTIFY')) {
1281  ?>
1282 // Defined properties for JNotify
1283 $(document).ready(function() {
1284  if (typeof $.jnotify == 'function') {
1285  $.jnotify.setup({
1286  delay: 3000 // the default time to show each notification (in milliseconds)
1287  , sticky: false // determines if the message should be considered "sticky" (user must manually close notification)
1288  , closeLabel: "&times;" // the HTML to use for the "Close" link
1289  , showClose: true // determines if the "Close" link should be shown if notification is also sticky
1290  , fadeSpeed: 1000 // the speed to fade messages out (in milliseconds)
1291  , slideSpeed: 250 // the speed used to slide messages out (in milliseconds)
1292  , classContainer: "jnotify-container"
1293  , classNotification: "jnotify-notification"
1294  , classBackground: "jnotify-background"
1295  , classClose: "jnotify-close"
1296  , classMessage: "jnotify-message"
1297  , init: null // callback that occurs when the main jnotify container is created
1298  , create: null // callback that occurs when when the note is created (occurs just before appearing in DOM)
1299  , beforeRemove: null // callback that occurs when before the notification starts to fade away
1300  });
1301  }
1302 });
1303  <?php
1304 } ?>
1305 
1306 
1307 
1308 jQuery(document).ready(function() {
1309  // Force to hide menus when page is inside an iFrame so we can show any page into a dialog popup
1310  if (window.location && window.location.pathname.indexOf("externalsite/frametop.php") == -1 && window.location !== window.parent.location ) {
1311  console.log("Page is detected to be into an iframe, we hide by CSS the menus");
1312  // The page is in an iframe
1313  jQuery(".side-nav-vert, .side-nav, .websitebar").hide();
1314  jQuery(".id-container").css('width', '100%');
1315 
1316  }
1317 
1318  // Code to set tooltip on search field
1319  jQuery('table.liste tr.liste_titre_filter td.liste_titre input[name^="search"][type=text]:not(".maxwidthdate")').attr('title', '<?php echo dol_escape_js($langs->transnoentities("SearchSyntaxTooltipForStringOrNum")) ?>');
1320 });
1321 
1322 
1323 jQuery(document).ready(function() {
1324  jQuery(".butAction.dropdown-toggle").on("click", function(event) {
1325  console.log("Click on .butAction.dropdown-toggle");
1326  var parentholder = jQuery(".butAction.dropdown-toggle").closest(".dropdown");
1327  var offset = parentholder.offset();
1328  var widthdocument = $(document).width();
1329  var left = offset.left;
1330  var right = widthdocument - offset.left - parentholder.width();
1331  var widthpopup = parentholder.children(".dropdown-content").width();
1332  console.log("left="+left+" right="+right+" width="+widthpopup+" widthdocument="+widthdocument);
1333  if (widthpopup + right >= widthdocument) {
1334  right = 10;
1335  }
1336  parentholder.toggleClass("open");
1337  parentholder.children(".dropdown-content").css({"right": right+"px", "left": "auto"});
1338  });
1339 });
1340 
1341 
1342 <?php
1343 if (!getDolGlobalString('MAIN_DISABLE_SELECT2_FOCUS_PROTECTION') && !defined('DISABLE_SELECT2_FOCUS_PROTECTION')) {
1344  ?>
1345 /*
1346  * Hacky fix for a bug in select2 with jQuery 3.6.4's new nested-focus "protection"
1347  * This fix needs to click a second time when clicking into a combo with ajax (see Test4d and Test5a in test_forms.php
1348  * see: https://github.com/select2/select2/issues/5993
1349  * see: https://github.com/jquery/jquery/issues/4382
1350  *
1351  * TODO: Recheck with the select2 GH issue and remove once this is fixed on their side
1352  */
1353 $(document).on('select2:open', (e) => {
1354  console.log("Execute the focus (click on combo or use space when on component");
1355  const target = $(e.target);
1356  if (target && target.length) {
1357  let id = target[0].id || target[0].name;
1358  if (id.substr(-2) == "[]") id = id.substr(0,id.length-2);
1359  document.querySelector('input[aria-controls*='+id+']').focus();
1360  }
1361 });
1362  <?php
1363 }
1364 ?>
1365 
1366 
1367 // End of lib_head.js.php
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
ui state ui widget content ui state ui widget header ui state a ui button
0 = Do not include form tag and submit button -1 = Do not include form tag but include submit button
td weekend span amount
Definition: global.inc.php:561
getParameterByName(name, valueifnotfound)
copyToClipboard(text, text2)
Function to output a dialog box for copy/paste.
document_preview(file, type, title)
Function show document preview.
pricejs(amount, mode='MT', currency_code='', force_locale='')
Function similar to PHP price()
newpopup(url, title)
Show a popup HTML page.
price2numjs(amount)
Function similar to PHP price2num()
if(!defined('NOREQUIREMENU')) if(!empty(GETPOST('seteventmessages', 'alpha'))) if(!function_exists("llxHeader")) top_httphead($contenttype='text/html', $forcenocache=0)
Show HTTP header.
Definition: main.inc.php:1650
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:139
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:142
print *****$script_file(".$version.") pid code
1: frais de port 2: ecotaxe 3: option line (when qty = 0)
fail($message)
Abort invoice creation with a given error message.
Definition: invoice.php:92