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