dolibarr  18.0.6
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  if (preg_match('/onrightofpage/', $morecss)) { // when $morecss contains 'onrightofpage', the select2 component must also be inside a parent with class="parentonrightofpage"
485  $msg .= ' dropdownAutoWidth: true, dropdownParent: $(\'#'.$htmlname.'\').parent(), '."\n";
486  }
487  $msg .= ' width: \''.dol_escape_js($widthTypeOfAutocomplete).'\', /* off or resolve */
488  minimumInputLength: '.((int) $minLengthToAutocomplete).',
489  language: select2arrayoflanguage,
490  matcher: function (params, data) {
491  if ($.trim(params.term) === "") {
492  return data;
493  }
494  keywords = (params.term).split(" ");
495  for (var i = 0; i < keywords.length; i++) {
496  if (((data.text).toUpperCase()).indexOf((keywords[i]).toUpperCase()) == -1) {
497  return null;
498  }
499  }
500  return data;
501  },
502  theme: \'default'.$moreselect2theme.'\', /* to add css on generated html components */
503  containerCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
504  selectionCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
505  dropdownCssClass: \'ui-dialog\',
506  templateResult: function (data, container) { /* Format visible output into combo list */
507  /* Code to add class of origin OPTION propagated to the new select2 <li> tag */
508  if (data.element) { $(container).addClass($(data.element).attr("class")); }
509  //console.log("data html is "+$(data.element).attr("data-html"));
510  if (data.id == '.((int) $idforemptyvalue).' && $(data.element).attr("data-html") == undefined) {
511  return \'&nbsp;\';
512  }
513  if ($(data.element).attr("data-html") != undefined) {
514  /* If property html set, we decode html entities and use this. */
515  /* Note that HTML content must have been sanitized from js with dol_escape_htmltag(xxx, 0, 0, \'\', 0, 1) when building the select option. */
516  return htmlEntityDecodeJs($(data.element).attr("data-html"));
517  }
518  return data.text;
519  },
520  templateSelection: function (selection) { /* Format visible output of selected value */
521  if (selection.id == '.((int) $idforemptyvalue).') return \'<span class="placeholder">\'+selection.text+\'</span>\';
522  return selection.text;
523  },
524  escapeMarkup: function(markup) {
525  return markup;
526  }
527  })';
528  if ($forcefocus) {
529  $msg .= '.select2(\'focus\')';
530  }
531  $msg .= ';'."\n";
532 
533  $msg .= '});'."\n";
534  $msg .= "</script>\n";
535 
536  $msg .= ajax_event($htmlname, $events);
537 
538  return $msg;
539 }
540 
541 
550 function ajax_event($htmlname, $events)
551 {
552  $out = '';
553 
554  if (is_array($events) && count($events)) { // If an array of js events to do were provided.
555  $out = '<!-- JS code to manage event for id = ' . $htmlname . ' -->
556  <script>
557  $(document).ready(function () {
558  jQuery("#'.$htmlname.'").change(function () {
559  var obj = '.json_encode($events) . ';
560  $.each(obj, function(key,values) {
561  if (values.method.length) {
562  runJsCodeForEvent'.$htmlname.'(values);
563  }
564  });
565  });
566  function runJsCodeForEvent'.$htmlname.'(obj) {
567  var id = $("#'.$htmlname.'").val();
568  var method = obj.method;
569  var url = obj.url;
570  var htmlname = obj.htmlname;
571  var showempty = obj.showempty;
572  console.log("Run runJsCodeForEvent-'.$htmlname.' from ajax_combobox id="+id+" method="+method+" showempty="+showempty+" url="+url+" htmlname="+htmlname);
573  $.getJSON(url,
574  {
575  action: method,
576  id: id,
577  htmlname: htmlname,
578  showempty: showempty
579  },
580  function(response) {
581  $.each(obj.params, function(key,action) {
582  if (key.length) {
583  var num = response.num;
584  if (num > 0) {
585  $("#" + key).removeAttr(action);
586  } else {
587  $("#" + key).attr(action, action);
588  }
589  }
590  });
591  $("select#" + htmlname).html(response.value);
592  if (response.num) {
593  var selecthtml_str = response.value;
594  var selecthtml_dom=$.parseHTML(selecthtml_str);
595  if (typeof(selecthtml_dom[0][0]) !== \'undefined\') {
596  $("#inputautocomplete"+htmlname).val(selecthtml_dom[0][0].innerHTML);
597  }
598  } else {
599  $("#inputautocomplete"+htmlname).val("");
600  }
601  $("select#" + htmlname).change(); /* Trigger event change */
602  }
603  );
604  }
605  });
606  </script>';
607  }
608 
609  return $out;
610 }
611 
612 
630 function ajax_constantonoff($code, $input = array(), $entity = null, $revertonoff = 0, $strict = 0, $forcereload = 0, $marginleftonlyshort = 2, $forcenoajax = 0, $setzeroinsteadofdel = 0, $suffix = '', $mode = '', $morecss = '')
631 {
632  global $conf, $langs, $user;
633 
634  $entity = ((isset($entity) && is_numeric($entity) && $entity >= 0) ? $entity : $conf->entity);
635  if (!isset($input)) {
636  $input = array();
637  }
638 
639  if (empty($conf->use_javascript_ajax) || $forcenoajax) {
640  if (empty($conf->global->$code)) {
641  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>';
642  } else {
643  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>';
644  }
645  } else {
646  $out = "\n<!-- Ajax code to switch constant ".$code." -->".'
647  <script>
648  $(document).ready(function() {
649  var input = '.json_encode($input).';
650  var url = \''.DOL_URL_ROOT.'/core/ajax/constantonoff.php\';
651  var code = \''.dol_escape_js($code).'\';
652  var entity = \''.dol_escape_js($entity).'\';
653  var strict = \''.dol_escape_js($strict).'\';
654  var userid = \''.dol_escape_js($user->id).'\';
655  var yesButton = \''.dol_escape_js($langs->transnoentities("Yes")).'\';
656  var noButton = \''.dol_escape_js($langs->transnoentities("No")).'\';
657  var token = \''.currentToken().'\';
658 
659  // Set constant
660  $("#set_" + code).click(function() {
661  if (input.alert && input.alert.set) {
662  if (input.alert.set.yesButton) yesButton = input.alert.set.yesButton;
663  if (input.alert.set.noButton) noButton = input.alert.set.noButton;
664  confirmConstantAction("set", url, code, input, input.alert.set, entity, yesButton, noButton, strict, userid, token);
665  } else {
666  setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token);
667  }
668  });
669 
670  // Del constant
671  $("#del_" + code).click(function() {
672  if (input.alert && input.alert.del) {
673  if (input.alert.del.yesButton) yesButton = input.alert.del.yesButton;
674  if (input.alert.del.noButton) noButton = input.alert.del.noButton;
675  confirmConstantAction("del", url, code, input, input.alert.del, entity, yesButton, noButton, strict, userid, token);
676  } else {';
677  if (empty($setzeroinsteadofdel)) {
678  $out .=' delConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token);';
679  } else {
680  $out .=' setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token, 0);';
681  }
682  $out .= ' }
683  });
684  });
685  </script>'."\n";
686 
687  $out .= '<div id="confirm_'.$code.'" title="" style="display: none;"></div>';
688  $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>';
689  $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>';
690  $out .= "\n";
691  }
692 
693  return $out;
694 }
695 
711 function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input = array(), $morecss = '', $htmlname = '', $forcenojs = 0)
712 {
713  global $conf, $langs;
714 
715  if (empty($htmlname)) {
716  $htmlname = $code;
717  }
718  //var_dump($object->module); var_dump($object->element);
719 
720  $out = '';
721 
722  if (!empty($conf->use_javascript_ajax)) {
723  $out .= '<script>
724  $(function() {
725  var input = '.json_encode($input).';
726 
727  // Set constant
728  $("#set_'.$htmlname.'_'.$object->id.'").click(function() {
729  console.log("Click managed by ajax_object_onoff");
730  $.get( "'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
731  action: \'set\',
732  field: \''.dol_escape_js($field).'\',
733  value: \'1\',
734  element: \''.dol_escape_js((empty($object->module) || $object->module == $object->element) ? $object->element : $object->element.'@'.$object->module).'\',
735  id: \''.((int) $object->id).'\',
736  token: \''.currentToken().'\'
737  },
738  function() {
739  $("#set_'.$htmlname.'_'.$object->id.'").hide();
740  $("#del_'.$htmlname.'_'.$object->id.'").show();
741  // Enable another element
742  if (input.disabled && input.disabled.length > 0) {
743  $.each(input.disabled, function(key,value) {
744  $("#" + value).removeAttr("disabled");
745  if ($("#" + value).hasClass("butActionRefused") == true) {
746  $("#" + value).removeClass("butActionRefused");
747  $("#" + value).addClass("butAction");
748  }
749  });
750  // Show another element
751  } else if (input.showhide && input.showhide.length > 0) {
752  $.each(input.showhide, function(key,value) {
753  $("#" + value).show();
754  });
755  }
756  });
757  });
758 
759  // Del constant
760  $("#del_'.$htmlname.'_'.$object->id.'").click(function() {
761  console.log("Click managed by ajax_object_onoff");
762  $.get( "'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
763  action: \'set\',
764  field: \''.dol_escape_js($field).'\',
765  value: \'0\',
766  element: \''.dol_escape_js((empty($object->module) || $object->module == $object->element) ? $object->element : $object->element.'@'.$object->module).'\',
767  id: \''.((int) $object->id).'\',
768  token: \''.currentToken().'\'
769  },
770  function() {
771  $("#del_'.$htmlname.'_'.$object->id.'").hide();
772  $("#set_'.$htmlname.'_'.$object->id.'").show();
773  // Disable another element
774  if (input.disabled && input.disabled.length > 0) {
775  $.each(input.disabled, function(key,value) {
776  $("#" + value).prop("disabled", true);
777  if ($("#" + value).hasClass("butAction") == true) {
778  $("#" + value).removeClass("butAction");
779  $("#" + value).addClass("butActionRefused");
780  }
781  });
782  // Hide another element
783  } else if (input.showhide && input.showhide.length > 0) {
784  $.each(input.showhide, function(key,value) {
785  $("#" + value).hide();
786  });
787  }
788  });
789  });
790  });
791  </script>';
792  }
793 
794  $switchon = 'switch_on';
795  $switchoff = 'switch_off';
796  $cssswitchon = '';
797  $cssswitchoff = '';
798  $tmparray = explode(':', $text_on);
799  if (!empty($tmparray[1])) {
800  $text_on = $tmparray[0];
801  $switchon = $tmparray[1];
802  if (!empty($tmparray[2])) {
803  $cssswitchon = $tmparray[2];
804  }
805  }
806  $tmparray = explode(':', $text_off);
807  if (!empty($tmparray[1])) {
808  $text_off = $tmparray[0];
809  $switchoff = $tmparray[1];
810  if (!empty($tmparray[2])) {
811  $cssswitchoff = $tmparray[2];
812  }
813  }
814 
815  if (empty($conf->use_javascript_ajax) || $forcenojs) {
816  $out .= '<a id="set_'.$htmlname.'_'.$object->id.'" class="linkobject '.($object->$code == 1 ? 'hideobject' : '').($morecss ? ' '.$morecss : '').'" href="'.DOL_URL_ROOT.'/core/ajax/objectonoff.php?action=set&token='.newToken().'&id='.((int) $object->id).'&element='.urlencode($object->element).'&field='.urlencode($field).'&value=1&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id).'">'.img_picto($langs->trans($text_off), $switchoff, '', false, 0, 0, '', $cssswitchoff).'</a>';
817  $out .= '<a id="del_'.$htmlname.'_'.$object->id.'" class="linkobject '.($object->$code == 1 ? '' : 'hideobject').($morecss ? ' '.$morecss : '').'" href="'.DOL_URL_ROOT.'/core/ajax/objectonoff.php?action=set&token='.newToken().'&id='.((int) $object->id).'&element='.urlencode($object->element).'&field='.urlencode($field).'&value=0&backtopage='.urlencode($_SERVER["PHP_SELF"].'?id='.$object->id).'">'.img_picto($langs->trans($text_on), $switchon, '', false, 0, 0, '', $cssswitchon).'</a>';
818  } else {
819  $out .= '<span id="set_'.$htmlname.'_'.$object->id.'" class="linkobject '.($object->$code == 1 ? 'hideobject' : '').($morecss ? ' '.$morecss : '').'">'.img_picto($langs->trans($text_off), $switchoff, '', false, 0, 0, '', $cssswitchoff).'</span>';
820  $out .= '<span id="del_'.$htmlname.'_'.$object->id.'" class="linkobject '.($object->$code == 1 ? '' : 'hideobject').($morecss ? ' '.$morecss : '').'">'.img_picto($langs->trans($text_on), $switchon, '', false, 0, 0, '', $cssswitchon).'</span>';
821  }
822 
823  return $out;
824 }
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:630
ajax_event($htmlname, $events)
Add event management script.
Definition: ajax.lib.php:550
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,...