dolibarr  x.y.z
ajax.lib.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2007-2010 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2007-2015 Regis Houssin <regis.houssin@inodbox.com>
4  * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.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 
47 function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLength = 2, $autoselect = 0, $ajaxoptions = array(), $moreparams = '')
48 {
49  global $conf;
50 
51  if (empty($minLength)) {
52  $minLength = 1;
53  }
54 
55  $dataforrenderITem = 'ui-autocomplete';
56  $dataforitem = 'ui-autocomplete-item';
57  // Allow two constant to use other values for backward compatibility
58  if (defined('JS_QUERY_AUTOCOMPLETE_RENDERITEM')) {
59  $dataforrenderITem = constant('JS_QUERY_AUTOCOMPLETE_RENDERITEM');
60  }
61  if (defined('JS_QUERY_AUTOCOMPLETE_ITEM')) {
62  $dataforitem = constant('JS_QUERY_AUTOCOMPLETE_ITEM');
63  }
64 
65  $htmlnamejquery = str_replace('.', '\\\\.', $htmlname);
66 
67  // Input search_htmlname is original field
68  // Input htmlname is a second input field used when using ajax autocomplete.
69  $script = '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'" value="'.$selected.'" '.($moreparams ? $moreparams : '').' />';
70 
71  $script .= '<!-- Javascript code for autocomplete of field '.$htmlname.' -->'."\n";
72  $script .= '<script>'."\n";
73  $script .= '$(document).ready(function() {
74  var autoselect = '.((int) $autoselect).';
75  var options = '.json_encode($ajaxoptions).'; /* Option of actions to do after keyup, or after select */
76 
77  /* Remove selected id as soon as we type or delete a char (it means old selection is wrong). Use keyup/down instead of change to avoid loosing the product id. This is needed only for select of predefined product */
78  $("input#search_'.$htmlnamejquery.'").keydown(function(e) {
79  if (e.keyCode != 9) /* If not "Tab" key */
80  {
81  if (e.keyCode == 13) { return false; } /* disable "ENTER" key useful for barcode readers */
82  console.log("Clear id previously selected for field '.$htmlname.'");
83  $("#'.$htmlnamejquery.'").val("");
84  }
85  });
86 
87  // Check options for secondary actions when keyup
88  $("input#search_'.$htmlnamejquery.'").keyup(function() {
89  if ($(this).val().length == 0)
90  {
91  $("#search_'.$htmlnamejquery.'").val("");
92  $("#'.$htmlnamejquery.'").val("").trigger("change");
93  if (options.option_disabled) {
94  $("#" + options.option_disabled).removeAttr("disabled");
95  }
96  if (options.disabled) {
97  $.each(options.disabled, function(key, value) {
98  $("#" + value).removeAttr("disabled");
99  });
100  }
101  if (options.update) {
102  $.each(options.update, function(key, value) {
103  $("#" + key).val("").trigger("change");
104  });
105  }
106  if (options.show) {
107  $.each(options.show, function(key, value) {
108  $("#" + value).hide().trigger("hide");
109  });
110  }
111  if (options.update_textarea) {
112  $.each(options.update_textarea, function(key, value) {
113  if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances[key] != "undefined") {
114  CKEDITOR.instances[key].setData("");
115  } else {
116  $("#" + key).html("");
117  }
118  });
119  }
120  }
121  });
122 
123  $("input#search_'.$htmlnamejquery.'").autocomplete({
124  source: function( request, response ) {
125  $.get("'.$url.($urloption ? '?'.$urloption : '').'", { "'.str_replace('.', '_', $htmlname).'": request.term }, function(data){
126  if (data != null)
127  {
128  response($.map( data, function(item) {
129  if (autoselect == 1 && data.length == 1) {
130  $("#search_'.$htmlnamejquery.'").val(item.value);
131  $("#'.$htmlnamejquery.'").val(item.key).trigger("change");
132  }
133  var label = "";
134  if (item.label != null) {
135  label = item.label.toString();
136  }
137  var update = {};
138  if (options.update) {
139  $.each(options.update, function(key, value) {
140  update[key] = item[value];
141  });
142  }
143  var textarea = {};
144  if (options.update_textarea) {
145  $.each(options.update_textarea, function(key, value) {
146  textarea[key] = item[value];
147  });
148  }
149 
150  console.log("Return value from GET to the rest of code");
151  return { label: label,
152  value: item.value,
153  id: item.key,
154  disabled: item.disabled,
155  update: update,
156  textarea: textarea,
157  pbq: item.pbq,
158  type: item.type,
159  qty: item.qty,
160  discount: item.discount,
161  pricebasetype: item.pricebasetype,
162  price_ht: item.price_ht,
163  price_ttc: item.price_ttc,
164  price_unit_ht: item.price_unit_ht,
165  price_unit_ht_locale: item.price_unit_ht_locale,
166  description : item.description,
167  ref_customer: item.ref_customer,
168  tva_tx: item.tva_tx,
169  default_vat_code: item.default_vat_code
170  }
171  }));
172  } else {
173  console.error("Error: Ajax url '.$url.($urloption ? '?'.$urloption : '').' has returned an empty page. Should be an empty json array.");
174  }
175  }, "json");
176  },
177  dataType: "json",
178  minLength: '.((int) $minLength).',
179  select: function( event, ui ) { // Function ran once new value has been selected into javascript combo
180  console.log("We will trigger change on input '.$htmlname.' because of the select definition of autocomplete code for input#search_'.$htmlname.'");
181  console.log("Selected id = "+ui.item.id+" - If this value is null, it means you select a record with key that is null so selection is not effective");
182 
183  console.log("Propagate before some properties retrieved by ajax into data-xxx properties of #'.$htmlnamejquery.' component");
184  //console.log(ui.item);
185 
186  // For supplier price and customer when price by quantity is off
187  $("#'.$htmlnamejquery.'").attr("data-up", ui.item.price_ht);
188  $("#'.$htmlnamejquery.'").attr("data-up-locale", ui.item.price_unit_ht_locale);
189  $("#'.$htmlnamejquery.'").attr("data-base", ui.item.pricebasetype);
190  $("#'.$htmlnamejquery.'").attr("data-qty", ui.item.qty);
191  $("#'.$htmlnamejquery.'").attr("data-discount", ui.item.discount);
192  $("#'.$htmlnamejquery.'").attr("data-description", ui.item.description);
193  $("#'.$htmlnamejquery.'").attr("data-ref-customer", ui.item.ref_customer);
194  $("#'.$htmlnamejquery.'").attr("data-tvatx", ui.item.tva_tx);
195  $("#'.$htmlnamejquery.'").attr("data-default-vat-code", ui.item.default_vat_code);
196  ';
197  if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY) || !empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES)) {
198  $script .= '
199  // For customer price when PRODUIT_CUSTOMER_PRICES_BY_QTY is on
200  console.log("PRODUIT_CUSTOMER_PRICES_BY_QTY is on, propagate also prices by quantity into data-pbqxxx properties");
201  $("#'.$htmlnamejquery.'").attr("data-pbq", ui.item.pbq);
202  $("#'.$htmlnamejquery.'").attr("data-pbqup", ui.item.price_ht);
203  $("#'.$htmlnamejquery.'").attr("data-pbqbase", ui.item.pricebasetype);
204  $("#'.$htmlnamejquery.'").attr("data-pbqqty", ui.item.qty);
205  $("#'.$htmlnamejquery.'").attr("data-pbqpercent", ui.item.discount);
206  ';
207  }
208  $script .= '
209  // A new value has been selected, we trigger the handlers on #htmlnamejquery
210  console.log("Trigger changes on #'.$htmlnamejquery.'");
211  $("#'.$htmlnamejquery.'").val(ui.item.id).trigger("change"); // Select new value
212 
213  // Complementary actions
214 
215  // Disable an element
216  if (options.option_disabled) {
217  console.log("Make action option_disabled on #"+options.option_disabled+" with disabled="+ui.item.disabled)
218  if (ui.item.disabled) {
219  $("#" + options.option_disabled).prop("disabled", true);
220  if (options.error) {
221  $.jnotify(options.error, "error", true); // Output with jnotify the error message
222  }
223  if (options.warning) {
224  $.jnotify(options.warning, "warning", false); // Output with jnotify the warning message
225  }
226  } else {
227  $("#" + options.option_disabled).removeAttr("disabled");
228  }
229  }
230 
231  if (options.disabled) {
232  console.log("Make action disabled on each "+options.option_disabled)
233  $.each(options.disabled, function(key, value) {
234  $("#" + value).prop("disabled", true);
235  });
236  }
237  if (options.show) {
238  console.log("Make action show on each "+options.show)
239  $.each(options.show, function(key, value) {
240  $("#" + value).show().trigger("show");
241  });
242  }
243 
244  // Update an input
245  if (ui.item.update) {
246  console.log("Make action update on each ui.item.update (if there is)")
247  // loop on each "update" fields
248  $.each(ui.item.update, function(key, value) {
249  console.log("Set value "+value+" into #"+key);
250  $("#" + key).val(value).trigger("change");
251  });
252  }
253  if (ui.item.textarea) {
254  console.log("Make action textarea on each ui.item.textarea (if there is)")
255  $.each(ui.item.textarea, function(key, value) {
256  if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances[key] != "undefined") {
257  CKEDITOR.instances[key].setData(value);
258  CKEDITOR.instances[key].focus();
259  } else {
260  $("#" + key).html(value);
261  $("#" + key).focus();
262  }
263  });
264  }
265  console.log("ajax_autocompleter new value selected, we trigger change also on original component so on field #search_'.$htmlname.'");
266 
267  $("#search_'.$htmlnamejquery.'").trigger("change"); // We have changed value of the combo select, we must be sure to trigger all js hook binded on this event. This is required to trigger other javascript change method binded on original field by other code.
268  }
269  ,delay: 500
270  }).data("'.$dataforrenderITem.'")._renderItem = function( ul, item ) {
271  return $("<li>")
272  .data( "'.$dataforitem.'", item ) // jQuery UI > 1.10.0
273  .append( \'<a><span class="tag">\' + item.label + "</span></a>" )
274  .appendTo(ul);
275  };
276 
277  });';
278  $script .= '</script>';
279 
280  return $script;
281 }
282 
297 function ajax_multiautocompleter($htmlname, $fields, $url, $option = '', $minLength = 2, $autoselect = 0)
298 {
299  $script = '<!-- Autocomplete -->'."\n";
300  $script .= '<script>';
301  $script .= 'jQuery(document).ready(function() {
302  var fields = '.json_encode($fields).';
303  var nboffields = fields.length;
304  var autoselect = '.$autoselect.';
305  //alert(fields + " " + nboffields);
306 
307  jQuery("input#'.$htmlname.'").autocomplete({
308  dataType: "json",
309  minLength: '.$minLength.',
310  source: function( request, response ) {
311  jQuery.getJSON( "'.$url.($option ? '?'.$option : '').'", { '.$htmlname.': request.term }, function(data){
312  response( jQuery.map( data, function( item ) {
313  if (autoselect == 1 && data.length == 1) {
314  jQuery("#'.$htmlname.'").val(item.value);
315  // TODO move this to specific request
316  if (item.states) {
317  jQuery("#state_id").html(item.states);
318  }
319  for (i=0;i<nboffields;i++) {
320  if (item[fields[i]]) { // If defined
321  //alert(item[fields[i]]);
322  jQuery("#" + fields[i]).val(item[fields[i]]);
323  }
324  }
325  }
326  return item
327  }));
328  });
329  },
330  select: function( event, ui ) {
331  needtotrigger = "";
332  for (i=0;i<nboffields;i++) {
333  //alert(fields[i] + " = " + ui.item[fields[i]]);
334  if (fields[i]=="selectcountry_id")
335  {
336  if (ui.item[fields[i]] > 0) // Do not erase country if unknown
337  {
338  oldvalue=jQuery("#" + fields[i]).val();
339  newvalue=ui.item[fields[i]];
340  //alert(oldvalue+" "+newvalue);
341  jQuery("#" + fields[i]).val(ui.item[fields[i]]);
342  if (oldvalue != newvalue) // To force select2 to refresh visible content
343  {
344  needtotrigger="#" + fields[i];
345  }
346 
347  // If we set new country and new state, we need to set a new list of state to allow change
348  if (ui.item.states && ui.item["state_id"] != jQuery("#state_id").value) {
349  jQuery("#state_id").html(ui.item.states);
350  }
351  }
352  }
353  else if (fields[i]=="state_id" || fields[i]=="state_id")
354  {
355  if (ui.item[fields[i]] > 0) // Do not erase state if unknown
356  {
357  oldvalue=jQuery("#" + fields[i]).val();
358  newvalue=ui.item[fields[i]];
359  //alert(oldvalue+" "+newvalue);
360  jQuery("#" + fields[i]).val(ui.item[fields[i]]); // This may fails if not correct country
361  if (oldvalue != newvalue) // To force select2 to refresh visible content
362  {
363  needtotrigger="#" + fields[i];
364  }
365  }
366  }
367  else if (ui.item[fields[i]]) { // If defined
368  oldvalue=jQuery("#" + fields[i]).val();
369  newvalue=ui.item[fields[i]];
370  //alert(oldvalue+" "+newvalue);
371  jQuery("#" + fields[i]).val(ui.item[fields[i]]);
372  if (oldvalue != newvalue) // To force select2 to refresh visible content
373  {
374  needtotrigger="#" + fields[i];
375  }
376  }
377 
378  if (needtotrigger != "") // To force select2 to refresh visible content
379  {
380  // We introduce a delay so hand is back to js and all other js change can be done before the trigger that may execute a submit is done
381  // This is required for example when changing zip with autocomplete that change the country
382  jQuery(needtotrigger).delay(500).queue(function() {
383  jQuery(this).trigger("change");
384  });
385  }
386  }
387  }
388  });
389  });';
390  $script .= '</script>';
391 
392  return $script;
393 }
394 
404 function ajax_dialog($title, $message, $w = 350, $h = 150)
405 {
406  global $langs;
407 
408  $newtitle = dol_textishtml($title) ?dol_string_nohtmltag($title, 1) : $title;
409  $msg = '<div id="dialog-info" title="'.dol_escape_htmltag($newtitle).'">';
410  $msg .= $message;
411  $msg .= '</div>'."\n";
412  $msg .= '<script>
413  jQuery(function() {
414  jQuery("#dialog-info").dialog({
415  resizable: false,
416  height:'.$h.',
417  width:'.$w.',
418  modal: true,
419  buttons: {
420  Ok: function() {
421  jQuery(this).dialog(\'close\');
422  }
423  }
424  });
425  });
426  </script>';
427 
428  $msg .= "\n";
429 
430  return $msg;
431 }
432 
433 
449 function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = 0, $forcefocus = 0, $widthTypeOfAutocomplete = 'resolve', $idforemptyvalue = '-1', $morecss = '')
450 {
451  global $conf;
452 
453  // select2 can be disabled for smartphones
454  if (!empty($conf->browser->layout) && $conf->browser->layout == 'phone' && !empty($conf->global->MAIN_DISALLOW_SELECT2_WITH_SMARTPHONE)) {
455  return '';
456  }
457 
458  if (!empty($conf->global->MAIN_DISABLE_AJAX_COMBOX)) {
459  return '';
460  }
461  if (empty($conf->use_javascript_ajax)) {
462  return '';
463  }
464  if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && !defined('REQUIRE_JQUERY_MULTISELECT')) {
465  return '';
466  }
467  if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
468  return '';
469  }
470 
471  if (empty($minLengthToAutocomplete)) {
472  $minLengthToAutocomplete = 0;
473  }
474 
475  $moreselect2theme = ($morecss ? dol_escape_js(' '.$morecss) : '');
476  $moreselect2theme = preg_replace('/widthcentpercentminus[^\s]*/', '', $moreselect2theme);
477 
478  $tmpplugin = 'select2';
479  $msg = "\n".'<!-- JS CODE TO ENABLE '.$tmpplugin.' for id = '.$htmlname.' -->
480  <script>
481  $(document).ready(function () {
482  $(\''.(preg_match('/^\./', $htmlname) ? $htmlname : '#'.$htmlname).'\').'.$tmpplugin.'({
483  dir: \'ltr\',
484  width: \''.dol_escape_js($widthTypeOfAutocomplete).'\', /* off or resolve */
485  minimumInputLength: '.((int) $minLengthToAutocomplete).',
486  language: select2arrayoflanguage,
487  matcher: function (params, data) {
488  if ($.trim(params.term) === "") {
489  return data;
490  }
491  keywords = (params.term).split(" ");
492  for (var i = 0; i < keywords.length; i++) {
493  if (((data.text).toUpperCase()).indexOf((keywords[i]).toUpperCase()) == -1) {
494  return null;
495  }
496  }
497  return data;
498  },
499  theme: \'default'.$moreselect2theme.'\', /* to add css on generated html components */
500  containerCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
501  selectionCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
502  templateResult: function (data, container) { /* Format visible output into combo list */
503  /* Code to add class of origin OPTION propagated to the new select2 <li> tag */
504  if (data.element) { $(container).addClass($(data.element).attr("class")); }
505  //console.log($(data.element).attr("data-html"));
506  if (data.id == '.((int) $idforemptyvalue).' && $(data.element).attr("data-html") == undefined) {
507  return \'&nbsp;\';
508  }
509  if ($(data.element).attr("data-html") != undefined) return htmlEntityDecodeJs($(data.element).attr("data-html")); // If property html set, we decode html entities and use this
510  return data.text;
511  },
512  templateSelection: function (selection) { /* Format visible output of selected value */
513  if (selection.id == '.((int) $idforemptyvalue).') return \'<span class="placeholder">\'+selection.text+\'</span>\';
514  return selection.text;
515  },
516  escapeMarkup: function(markup) {
517  return markup;
518  },
519  dropdownCssClass: \'ui-dialog\'
520  })';
521  if ($forcefocus) {
522  $msg .= '.select2(\'focus\')';
523  }
524  $msg .= ';'."\n";
525 
526  if (is_array($events) && count($events)) { // If an array of js events to do were provided.
527  $msg .= '
528  jQuery("#'.$htmlname.'").change(function () {
529  var obj = '.json_encode($events).';
530  $.each(obj, function(key,values) {
531  if (values.method.length) {
532  runJsCodeForEvent'.$htmlname.'(values);
533  }
534  });
535  });
536 
537  function runJsCodeForEvent'.$htmlname.'(obj) {
538  var id = $("#'.$htmlname.'").val();
539  var method = obj.method;
540  var url = obj.url;
541  var htmlname = obj.htmlname;
542  var showempty = obj.showempty;
543  console.log("Run runJsCodeForEvent-'.$htmlname.' from ajax_combobox id="+id+" method="+method+" showempty="+showempty+" url="+url+" htmlname="+htmlname);
544  $.getJSON(url,
545  {
546  action: method,
547  id: id,
548  htmlname: htmlname,
549  showempty: showempty
550  },
551  function(response) {
552  $.each(obj.params, function(key,action) {
553  if (key.length) {
554  var num = response.num;
555  if (num > 0) {
556  $("#" + key).removeAttr(action);
557  } else {
558  $("#" + key).attr(action, action);
559  }
560  }
561  });
562  $("select#" + htmlname).html(response.value);
563  if (response.num) {
564  var selecthtml_str = response.value;
565  var selecthtml_dom=$.parseHTML(selecthtml_str);
566  if (typeof(selecthtml_dom[0][0]) !== \'undefined\') {
567  $("#inputautocomplete"+htmlname).val(selecthtml_dom[0][0].innerHTML);
568  }
569  } else {
570  $("#inputautocomplete"+htmlname).val("");
571  }
572  $("select#" + htmlname).change(); /* Trigger event change */
573  }
574  );
575  }';
576  }
577 
578  $msg .= '});'."\n";
579  $msg .= "</script>\n";
580 
581  return $msg;
582 }
583 
601 function ajax_constantonoff($code, $input = array(), $entity = null, $revertonoff = 0, $strict = 0, $forcereload = 0, $marginleftonlyshort = 2, $forcenoajax = 0, $setzeroinsteadofdel = 0, $suffix = '', $mode = '', $morecss = '')
602 {
603  global $conf, $langs, $user;
604 
605  $entity = ((isset($entity) && is_numeric($entity) && $entity >= 0) ? $entity : $conf->entity);
606  if (!isset($input)) {
607  $input = array();
608  }
609 
610  if (empty($conf->use_javascript_ajax) || $forcenoajax) {
611  if (empty($conf->global->$code)) {
612  print '<a '.($morecss ? 'class="'.$morecss.'" ' : '').'href="'.$_SERVER['PHP_SELF'].'?action=set_'.$code.'&token='.newToken().'&entity='.$entity.($mode ? '&mode='.$mode : '').($forcereload ? '&dol_resetcache=1' : '').'">'.img_picto($langs->trans("Disabled"), 'off').'</a>';
613  } else {
614  print '<a '.($morecss ? 'class="'.$morecss.'" ' : '').' href="'.$_SERVER['PHP_SELF'].'?action=del_'.$code.'&token='.newToken().'&entity='.$entity.($mode ? '&mode='.$mode : '').($forcereload ? '&dol_resetcache=1' : '').'">'.img_picto($langs->trans("Enabled"), 'on').'</a>';
615  }
616  } else {
617  $out = "\n<!-- Ajax code to switch constant ".$code." -->".'
618  <script>
619  $(document).ready(function() {
620  var input = '.json_encode($input).';
621  var url = \''.DOL_URL_ROOT.'/core/ajax/constantonoff.php\';
622  var code = \''.dol_escape_js($code).'\';
623  var entity = \''.dol_escape_js($entity).'\';
624  var strict = \''.dol_escape_js($strict).'\';
625  var userid = \''.dol_escape_js($user->id).'\';
626  var yesButton = \''.dol_escape_js($langs->transnoentities("Yes")).'\';
627  var noButton = \''.dol_escape_js($langs->transnoentities("No")).'\';
628  var token = \''.currentToken().'\';
629 
630  // Set constant
631  $("#set_" + code).click(function() {
632  if (input.alert && input.alert.set) {
633  if (input.alert.set.yesButton) yesButton = input.alert.set.yesButton;
634  if (input.alert.set.noButton) noButton = input.alert.set.noButton;
635  confirmConstantAction("set", url, code, input, input.alert.set, entity, yesButton, noButton, strict, userid, token);
636  } else {
637  setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token);
638  }
639  });
640 
641  // Del constant
642  $("#del_" + code).click(function() {
643  if (input.alert && input.alert.del) {
644  if (input.alert.del.yesButton) yesButton = input.alert.del.yesButton;
645  if (input.alert.del.noButton) noButton = input.alert.del.noButton;
646  confirmConstantAction("del", url, code, input, input.alert.del, entity, yesButton, noButton, strict, userid, token);
647  } else {';
648  if (empty($setzeroinsteadofdel)) {
649  $out .=' delConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token);';
650  } else {
651  $out .=' setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token, 0);';
652  }
653  $out .= ' }
654  });
655  });
656  </script>'."\n";
657 
658  $out .= '<div id="confirm_'.$code.'" title="" style="display: none;"></div>';
659  $out .= '<span id="set_'.$code.'" class="valignmiddle linkobject '.(!empty($conf->global->$code) ? 'hideobject' : '').'">'.($revertonoff ?img_picto($langs->trans("Enabled"), 'switch_on', '', false, 0, 0, '', '', $marginleftonlyshort) : img_picto($langs->trans("Disabled"), 'switch_off', '', false, 0, 0, '', '', $marginleftonlyshort)).'</span>';
660  $out .= '<span id="del_'.$code.'" class="valignmiddle linkobject '.(!empty($conf->global->$code) ? '' : 'hideobject').'">'.($revertonoff ?img_picto($langs->trans("Disabled"), 'switch_off'.$suffix, '', false, 0, 0, '', '', $marginleftonlyshort) : img_picto($langs->trans("Enabled"), 'switch_on'.$suffix, '', false, 0, 0, '', '', $marginleftonlyshort)).'</span>';
661  $out .= "\n";
662  }
663 
664  return $out;
665 }
666 
681 function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input = array(), $morecss = '', $htmlname = '')
682 {
683  global $langs;
684 
685  if (empty($htmlname)) {
686  $htmlname = $code;
687  }
688 
689  $out = '<script>
690  $(function() {
691  var input = '.json_encode($input).';
692 
693  // Set constant
694  $("#set_'.$htmlname.'_'.$object->id.'").click(function() {
695  console.log("Click managed by ajax_object_onoff");
696  $.get( "'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
697  action: \'set\',
698  field: \''.dol_escape_js($field).'\',
699  value: \'1\',
700  element: \''.dol_escape_js($object->element).'\',
701  id: \''.$object->id.'\',
702  token: \''.currentToken().'\'
703  },
704  function() {
705  $("#set_'.$htmlname.'_'.$object->id.'").hide();
706  $("#del_'.$htmlname.'_'.$object->id.'").show();
707  // Enable another element
708  if (input.disabled && input.disabled.length > 0) {
709  $.each(input.disabled, function(key,value) {
710  $("#" + value).removeAttr("disabled");
711  if ($("#" + value).hasClass("butActionRefused") == true) {
712  $("#" + value).removeClass("butActionRefused");
713  $("#" + value).addClass("butAction");
714  }
715  });
716  // Show another element
717  } else if (input.showhide && input.showhide.length > 0) {
718  $.each(input.showhide, function(key,value) {
719  $("#" + value).show();
720  });
721  }
722  });
723  });
724 
725  // Del constant
726  $("#del_'.$htmlname.'_'.$object->id.'").click(function() {
727  console.log("Click managed by ajax_object_onoff");
728  $.get( "'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
729  action: \'set\',
730  field: \''.dol_escape_js($field).'\',
731  value: \'0\',
732  element: \''.dol_escape_js($object->element).'\',
733  id: \''.$object->id.'\',
734  token: \''.currentToken().'\'
735  },
736  function() {
737  $("#del_'.$htmlname.'_'.$object->id.'").hide();
738  $("#set_'.$htmlname.'_'.$object->id.'").show();
739  // Disable another element
740  if (input.disabled && input.disabled.length > 0) {
741  $.each(input.disabled, function(key,value) {
742  $("#" + value).prop("disabled", true);
743  if ($("#" + value).hasClass("butAction") == true) {
744  $("#" + value).removeClass("butAction");
745  $("#" + value).addClass("butActionRefused");
746  }
747  });
748  // Hide another element
749  } else if (input.showhide && input.showhide.length > 0) {
750  $.each(input.showhide, function(key,value) {
751  $("#" + value).hide();
752  });
753  }
754  });
755  });
756  });
757  </script>';
758  $out .= '<span id="set_'.$htmlname.'_'.$object->id.'" class="linkobject '.($object->$code == 1 ? 'hideobject' : '').($morecss ? ' '.$morecss : '').'">'.img_picto($langs->trans($text_off), 'switch_off').'</span>';
759  $out .= '<span id="del_'.$htmlname.'_'.$object->id.'" class="linkobject '.($object->$code == 1 ? '' : 'hideobject').($morecss ? ' '.$morecss : '').'">'.img_picto($langs->trans($text_on), 'switch_on').'</span>';
760 
761  return $out;
762 }
ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLength=2, $autoselect=0, $ajaxoptions=array(), $moreparams='')
Generic function that return javascript to add to a page to transform a common input field into an au...
Definition: ajax.lib.php:47
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition: ajax.lib.php:449
ajax_dialog($title, $message, $w=350, $h=150)
Show an ajax dialog.
Definition: ajax.lib.php:404
ajax_multiautocompleter($htmlname, $fields, $url, $option='', $minLength=2, $autoselect=0)
Generic function that return javascript to add to a page to transform a common input field into an au...
Definition: ajax.lib.php:297
ajax_constantonoff($code, $input=array(), $entity=null, $revertonoff=0, $strict=0, $forcereload=0, $marginleftonlyshort=2, $forcenoajax=0, $setzeroinsteadofdel=0, $suffix='', $mode='', $morecss='')
On/off button for constant.
Definition: ajax.lib.php:601
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dol_textishtml($msg, $option=0)
Return if a text is a html content.
if(!defined( 'CSRFCHECK_WITH_TOKEN'))
print *****$script_file(".$version.") pid code
! Closing after partial payment: discount_vat, badcustomer or badsupplier, bankcharge,...