dolibarr  17.0.4
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 
600 function ajax_constantonoff($code, $input = array(), $entity = null, $revertonoff = 0, $strict = 0, $forcereload = 0, $marginleftonlyshort = 2, $forcenoajax = 0, $setzeroinsteadofdel = 0, $suffix = '', $mode = '')
601 {
602  global $conf, $langs, $user;
603 
604  $entity = ((isset($entity) && is_numeric($entity) && $entity >= 0) ? $entity : $conf->entity);
605  if (!isset($input)) {
606  $input = array();
607  }
608 
609  if (empty($conf->use_javascript_ajax) || $forcenoajax) {
610  if (empty($conf->global->$code)) {
611  print '<a 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>';
612  } else {
613  print '<a 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>';
614  }
615  } else {
616  $out = "\n<!-- Ajax code to switch constant ".$code." -->".'
617  <script>
618  $(document).ready(function() {
619  var input = '.json_encode($input).';
620  var url = \''.DOL_URL_ROOT.'/core/ajax/constantonoff.php\';
621  var code = \''.dol_escape_js($code).'\';
622  var entity = \''.dol_escape_js($entity).'\';
623  var strict = \''.dol_escape_js($strict).'\';
624  var userid = \''.dol_escape_js($user->id).'\';
625  var yesButton = \''.dol_escape_js($langs->transnoentities("Yes")).'\';
626  var noButton = \''.dol_escape_js($langs->transnoentities("No")).'\';
627  var token = \''.currentToken().'\';
628 
629  // Set constant
630  $("#set_" + code).click(function() {
631  if (input.alert && input.alert.set) {
632  if (input.alert.set.yesButton) yesButton = input.alert.set.yesButton;
633  if (input.alert.set.noButton) noButton = input.alert.set.noButton;
634  confirmConstantAction("set", url, code, input, input.alert.set, entity, yesButton, noButton, strict, userid, token);
635  } else {
636  setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token);
637  }
638  });
639 
640  // Del constant
641  $("#del_" + code).click(function() {
642  if (input.alert && input.alert.del) {
643  if (input.alert.del.yesButton) yesButton = input.alert.del.yesButton;
644  if (input.alert.del.noButton) noButton = input.alert.del.noButton;
645  confirmConstantAction("del", url, code, input, input.alert.del, entity, yesButton, noButton, strict, userid, token);
646  } else {';
647  if (empty($setzeroinsteadofdel)) {
648  $out .=' delConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token);';
649  } else {
650  $out .=' setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token, 0);';
651  }
652  $out .= ' }
653  });
654  });
655  </script>'."\n";
656 
657  $out .= '<div id="confirm_'.$code.'" title="" style="display: none;"></div>';
658  $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>';
659  $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>';
660  $out .= "\n";
661  }
662 
663  return $out;
664 }
665 
680 function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input = array(), $morecss = '', $htmlname = '')
681 {
682  global $langs;
683 
684  if (empty($htmlname)) {
685  $htmlname = $code;
686  }
687 
688  $out = '<script>
689  $(function() {
690  var input = '.json_encode($input).';
691 
692  // Set constant
693  $("#set_'.$htmlname.'_'.$object->id.'").click(function() {
694  console.log("Click managed by ajax_object_onoff");
695  $.get( "'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
696  action: \'set\',
697  field: \''.dol_escape_js($field).'\',
698  value: \'1\',
699  element: \''.dol_escape_js($object->element).'\',
700  id: \''.$object->id.'\',
701  token: \''.currentToken().'\'
702  },
703  function() {
704  $("#set_'.$htmlname.'_'.$object->id.'").hide();
705  $("#del_'.$htmlname.'_'.$object->id.'").show();
706  // Enable another element
707  if (input.disabled && input.disabled.length > 0) {
708  $.each(input.disabled, function(key,value) {
709  $("#" + value).removeAttr("disabled");
710  if ($("#" + value).hasClass("butActionRefused") == true) {
711  $("#" + value).removeClass("butActionRefused");
712  $("#" + value).addClass("butAction");
713  }
714  });
715  // Show another element
716  } else if (input.showhide && input.showhide.length > 0) {
717  $.each(input.showhide, function(key,value) {
718  $("#" + value).show();
719  });
720  }
721  });
722  });
723 
724  // Del constant
725  $("#del_'.$htmlname.'_'.$object->id.'").click(function() {
726  console.log("Click managed by ajax_object_onoff");
727  $.get( "'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
728  action: \'set\',
729  field: \''.dol_escape_js($field).'\',
730  value: \'0\',
731  element: \''.dol_escape_js($object->element).'\',
732  id: \''.$object->id.'\',
733  token: \''.currentToken().'\'
734  },
735  function() {
736  $("#del_'.$htmlname.'_'.$object->id.'").hide();
737  $("#set_'.$htmlname.'_'.$object->id.'").show();
738  // Disable another element
739  if (input.disabled && input.disabled.length > 0) {
740  $.each(input.disabled, function(key,value) {
741  $("#" + value).prop("disabled", true);
742  if ($("#" + value).hasClass("butAction") == true) {
743  $("#" + value).removeClass("butAction");
744  $("#" + value).addClass("butActionRefused");
745  }
746  });
747  // Hide another element
748  } else if (input.showhide && input.showhide.length > 0) {
749  $.each(input.showhide, function(key,value) {
750  $("#" + value).hide();
751  });
752  }
753  });
754  });
755  });
756  </script>';
757  $out .= '<span id="set_'.$htmlname.'_'.$object->id.'" class="linkobject '.($object->$code == 1 ? 'hideobject' : '').($morecss ? ' '.$morecss : '').'">'.img_picto($langs->trans($text_off), 'switch_off').'</span>';
758  $out .= '<span id="del_'.$htmlname.'_'.$object->id.'" class="linkobject '.($object->$code == 1 ? '' : 'hideobject').($morecss ? ' '.$morecss : '').'">'.img_picto($langs->trans($text_on), 'switch_on').'</span>';
759 
760  return $out;
761 }
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_constantonoff($code, $input=array(), $entity=null, $revertonoff=0, $strict=0, $forcereload=0, $marginleftonlyshort=2, $forcenoajax=0, $setzeroinsteadofdel=0, $suffix='', $mode='')
On/off button for constant.
Definition: ajax.lib.php:600
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
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,...