dolibarr 22.0.5
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 * Copyright (C) 2024-2025 MDW <mdeweerd@users.noreply.github.com>
6 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program. If not, see <https://www.gnu.org/licenses/>.
20 * or see https://www.gnu.org/
21 */
22
49function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLength = 2, $autoselect = 0, $ajaxoptions = array(), $moreparams = '')
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 losing 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 // Activate the autocomplete to execute the GET
124 $("input#search_'.$htmlnamejquery.'").autocomplete({
125 source: function( request, response ) {
126 $.get("'.$url.($urloption ? '?'.$urloption : '').'", { "'.str_replace('.', '_', $htmlname).'": request.term }, function(data){
127 if (data != null)
128 {
129 response($.map( data, function(item) {
130 console.log("Received answer from ajax GET, we populate array to return to the jquery autocomplete");
131 if (autoselect == 1 && data.length == 1) {
132 $("#search_'.$htmlnamejquery.'").val(item.value);
133 ';
134 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) {
135 $script .= '
136 // When product has only one price by qty and 1 result, must set data attributes before triggering change
137 $("#'.$htmlname.'").attr("data-pbq", item.pbq);
138 $("#'.$htmlname.'").attr("data-pbqup", item.price_ht);
139 $("#'.$htmlname.'").attr("data-pbqbase", item.pricebasetype);
140 $("#'.$htmlname.'").attr("data-pbqqty", item.qty);
141 $("#'.$htmlname.'").attr("data-pbqpercent", item.discount);
142 ';
143 }
144 $script .= '
145 $("#'.$htmlnamejquery.'").val(item.key).trigger("change");
146 }
147 var label = "";
148 if (item.labelhtml != null) {
149 label = item.labelhtml.toString();
150 } else if (item.label != null) {
151 label = item.label.toString();
152 }
153 var update = {};
154 if (options.update) {
155 $.each(options.update, function(key, value) {
156 update[key] = item[value];
157 });
158 }
159 var textarea = {};
160 if (options.update_textarea) {
161 $.each(options.update_textarea, function(key, value) {
162 textarea[key] = item[value];
163 });
164 }
165
166 return { label: label,
167 value: item.value,
168 id: item.key,
169 disabled: item.disabled,
170 update: update,
171 textarea: textarea,
172 pbq: item.pbq,
173 type: item.type,
174 qty: item.qty,
175 discount: item.discount,
176 pricebasetype: item.pricebasetype,
177 price_ht: item.price_ht,
178 price_ttc: item.price_ttc,
179 price_unit_ht: item.price_unit_ht,
180 price_unit_ht_locale: item.price_unit_ht_locale,
181 multicurrency_code: item.multicurrency_code,
182 multicurrency_unitprice: item.multicurrency_unitprice,
183 description : item.description,
184 ref_customer: item.ref_customer,
185 tva_tx: item.tva_tx,
186 default_vat_code: item.default_vat_code,
187 supplier_ref: item.supplier_ref
188 }
189 }));
190 } else {
191 console.error("Error: Ajax url '.$url.($urloption ? '?'.$urloption : '').' has returned an empty page. Should be an empty json array.");
192 }
193 }, "json");
194 },
195 dataType: "json",
196 minLength: '.((int) $minLength).',
197 select: function( event, ui ) { // Function ran once a new value has been selected into the javascript combo
198 console.log("We will trigger change on input '.$htmlname.' because of the select definition of autocomplete code for input#search_'.$htmlname.'");
199 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");
200
201 console.log("Before, we propagate some properties, retrieved by the ajax of the get, into the data-xxx properties of the component #'.$htmlnamejquery.'");
202 //console.log(ui.item);
203
204 // For supplier price and customer when price by quantity is off
205 $("#'.$htmlnamejquery.'").attr("data-up", ui.item.price_ht);
206 $("#'.$htmlnamejquery.'").attr("data-up-locale", ui.item.price_unit_ht_locale);
207 $("#'.$htmlnamejquery.'").attr("data-base", ui.item.pricebasetype);
208 $("#'.$htmlnamejquery.'").attr("data-qty", ui.item.qty);
209 $("#'.$htmlnamejquery.'").attr("data-discount", ui.item.discount);
210 $("#'.$htmlnamejquery.'").attr("data-description", ui.item.description);
211 $("#'.$htmlnamejquery.'").attr("data-ref-customer", ui.item.ref_customer);
212 $("#'.$htmlnamejquery.'").attr("data-tvatx", ui.item.tva_tx);
213 $("#'.$htmlnamejquery.'").attr("data-default-vat-code", ui.item.default_vat_code);
214 $("#'.$htmlnamejquery.'").attr("data-supplier-ref", ui.item.supplier_ref); // supplier_ref of price
215
216 // For multi-currency values
217 $("#'.$htmlnamejquery.'").attr("data-multicurrency-code", ui.item.multicurrency_code);
218 $("#'.$htmlnamejquery.'").attr("data-multicurrency-unitprice", ui.item.multicurrency_unitprice);
219 ';
220 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) {
221 $script .= '
222 // For customer price when PRODUIT_CUSTOMER_PRICES_BY_QTY is on
223 console.log("PRODUIT_CUSTOMER_PRICES_BY_QTY is on, so we propagate also prices by quantity into data-pbqxxx properties");
224 $("#'.$htmlnamejquery.'").attr("data-pbq", ui.item.pbq);
225 $("#'.$htmlnamejquery.'").attr("data-pbqup", ui.item.price_ht);
226 $("#'.$htmlnamejquery.'").attr("data-pbqbase", ui.item.pricebasetype);
227 $("#'.$htmlnamejquery.'").attr("data-pbqqty", ui.item.qty);
228 $("#'.$htmlnamejquery.'").attr("data-pbqpercent", ui.item.discount);
229 ';
230 }
231 $script .= '
232 // A new value has been selected, we trigger the handlers on #htmlnamejquery
233 console.log("Now, we trigger changes on #'.$htmlnamejquery.'");
234 $("#'.$htmlnamejquery.'").val(ui.item.id).trigger("change"); // Select new value
235
236 // Complementary actions
237
238 // Disable an element
239 if (options.option_disabled) {
240 console.log("Make action option_disabled on #"+options.option_disabled+" with disabled="+ui.item.disabled)
241 if (ui.item.disabled) {
242 $("#" + options.option_disabled).prop("disabled", true);
243 if (options.error) {
244 $.jnotify(options.error, "error", true); // Output with jnotify the error message
245 }
246 if (options.warning) {
247 $.jnotify(options.warning, "warning", false); // Output with jnotify the warning message
248 }
249 } else {
250 $("#" + options.option_disabled).removeAttr("disabled");
251 }
252 }
253
254 if (options.disabled) {
255 console.log("Make action \'disabled\' on each "+options.option_disabled)
256 $.each(options.disabled, function(key, value) {
257 $("#" + value).prop("disabled", true);
258 });
259 }
260 if (options.show) {
261 console.log("Make action \'show\' on each "+options.show)
262 $.each(options.show, function(key, value) {
263 $("#" + value).show().trigger("show");
264 });
265 }
266
267 // Update an input
268 if (ui.item.update) {
269 console.log("Make action \'update\' on each ui.item.update (if there is)")
270 // loop on each "update" fields
271 $.each(ui.item.update, function(key, value) {
272 console.log("Set value "+value+" into #"+key);
273 $("#" + key).val(value).trigger("change");
274 });
275 }
276 if (ui.item.textarea) {
277 console.log("Make action \'textarea\' on each ui.item.textarea (if there is)")
278 $.each(ui.item.textarea, function(key, value) {
279 if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances[key] != "undefined") {
280 CKEDITOR.instances[key].setData(value);
281 CKEDITOR.instances[key].focus();
282 } else {
283 $("#" + key).html(value);
284 $("#" + key).focus();
285 }
286 });
287 }
288 console.log("ajax_autocompleter new value selected, we trigger change also on original component so on field #search_'.$htmlname.'");
289
290 $("#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.
291 }
292 ,delay: 500
293 });
294 const widgetData = $("input#search_'.$htmlnamejquery.'").data("'.$dataforrenderITem.'");
295 if (widgetData) {
296 widgetData._renderItem = function( ul, item ) {
297 return $("<li>")
298 .data( "'.$dataforitem.'", item ) // jQuery UI > 1.10.0
299 .append( \'<a><span class="tag">\' + item.label + "</span></a>" )
300 .appendTo(ul);
301 };
302 }
303
304 });';
305 $script .= '</script>';
306
307 return $script;
308}
309
324function ajax_multiautocompleter($htmlname, $fields, $url, $option = '', $minLength = 2, $autoselect = 0)
325{
326 $script = '<!-- Autocomplete -->'."\n";
327 $script .= '<script>';
328 $script .= 'jQuery(document).ready(function() {
329 var fields = '.json_encode($fields).';
330 var nboffields = fields.length;
331 var autoselect = '.$autoselect.';
332 //alert(fields + " " + nboffields);
333
334 // Activate the autocomplete to execute the GET
335 jQuery("input#'.$htmlname.'").autocomplete({
336 dataType: "json",
337 minLength: '.$minLength.',
338 source: function( request, response ) {
339 jQuery.getJSON( "'.$url.($option ? '?'.$option : '').'", { '.$htmlname.': request.term }, function(data){
340 response( jQuery.map( data, function( item ) {
341 if (autoselect == 1 && data.length == 1) {
342 jQuery("#'.$htmlname.'").val(item.value);
343 // TODO move this to specific request
344 if (item.states) {
345 jQuery("#state_id").html(item.states);
346 }
347 for (i=0;i<nboffields;i++) {
348 if (item[fields[i]]) { // If defined
349 //alert(item[fields[i]]);
350 jQuery("#" + fields[i]).val(item[fields[i]]);
351 }
352 }
353 }
354 return item
355 }));
356 });
357 },
358 select: function( event, ui ) {
359 needtotrigger = "";
360 for (i=0;i<nboffields;i++) {
361 //alert(fields[i] + " = " + ui.item[fields[i]]);
362 if (fields[i]=="selectcountry_id")
363 {
364 if (ui.item[fields[i]] > 0) // Do not erase country if unknown
365 {
366 oldvalue=jQuery("#" + fields[i]).val();
367 newvalue=ui.item[fields[i]];
368 //alert(oldvalue+" "+newvalue);
369 jQuery("#" + fields[i]).val(ui.item[fields[i]]);
370 if (oldvalue != newvalue) // To force select2 to refresh visible content
371 {
372 needtotrigger="#" + fields[i];
373 }
374
375 // If we set new country and new state, we need to set a new list of state to allow change
376 if (ui.item.states && ui.item["state_id"] != jQuery("#state_id").value) {
377 jQuery("#state_id").html(ui.item.states);
378 }
379 }
380 }
381 else if (fields[i]=="state_id" || fields[i]=="state_id")
382 {
383 if (ui.item[fields[i]] > 0) // Do not erase state if unknown
384 {
385 oldvalue=jQuery("#" + fields[i]).val();
386 newvalue=ui.item[fields[i]];
387 //alert(oldvalue+" "+newvalue);
388 jQuery("#" + fields[i]).val(ui.item[fields[i]]); // This may fails if not correct country
389 if (oldvalue != newvalue) // To force select2 to refresh visible content
390 {
391 needtotrigger="#" + fields[i];
392 }
393 }
394 }
395 else if (ui.item[fields[i]]) { // If defined
396 oldvalue=jQuery("#" + fields[i]).val();
397 newvalue=ui.item[fields[i]];
398 //alert(oldvalue+" "+newvalue);
399 jQuery("#" + fields[i]).val(ui.item[fields[i]]);
400 if (oldvalue != newvalue) // To force select2 to refresh visible content
401 {
402 needtotrigger="#" + fields[i];
403 }
404 }
405
406 if (needtotrigger != "") // To force select2 to refresh visible content
407 {
408 // 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
409 // This is required for example when changing zip with autocomplete that change the country
410 jQuery(needtotrigger).delay(500).queue(function() {
411 jQuery(this).trigger("change");
412 });
413 }
414 }
415 }
416 });
417 });';
418 $script .= '</script>';
419
420 return $script;
421}
422
432function ajax_dialog($title, $message, $w = 350, $h = 150)
433{
434 $newtitle = dol_textishtml($title) ? dol_string_nohtmltag($title, 1) : $title;
435 $msg = '<div id="dialog-info" title="'.dol_escape_htmltag($newtitle).'">';
436 $msg .= $message;
437 $msg .= '</div>'."\n";
438 $msg .= '<script>
439 jQuery(function() {
440 jQuery("#dialog-info").dialog({
441 resizable: false,
442 height:'.$h.',
443 width:'.$w.',
444 modal: true,
445 buttons: {
446 Ok: function() {
447 jQuery(this).dialog(\'close\');
448 }
449 }
450 });
451 });
452 </script>';
453
454 $msg .= "\n";
455
456 return $msg;
457}
458
459
475function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = 0, $forcefocus = 0, $widthTypeOfAutocomplete = 'resolve', $idforemptyvalue = '-1', $morecss = '')
476{
477 global $conf;
478
479 // select2 can be disabled for smartphones
480 if (!empty($conf->browser->layout) && $conf->browser->layout == 'phone' && getDolGlobalString('MAIN_DISALLOW_SELECT2_WITH_SMARTPHONE')) {
481 return '';
482 }
483
484 if (getDolGlobalString('MAIN_DISABLE_AJAX_COMBOX')) {
485 return '';
486 }
487 if (empty($conf->use_javascript_ajax)) {
488 return '';
489 }
490 if (!getDolGlobalString('MAIN_USE_JQUERY_MULTISELECT') && !defined('REQUIRE_JQUERY_MULTISELECT')) {
491 return '';
492 }
493 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
494 return '';
495 }
496
497 if (empty($minLengthToAutocomplete)) {
498 $minLengthToAutocomplete = 0;
499 }
500
501 $moreselect2theme = ($morecss ? dol_escape_js(' '.$morecss) : '');
502 $moreselect2theme = preg_replace('/widthcentpercentminus[^\s]*/', '', $moreselect2theme);
503
504 $tmpplugin = 'select2';
505 $msg = "\n".'<!-- JS CODE TO ENABLE '.$tmpplugin.' for id = '.$htmlname.' -->
506 <script>
507 $(document).ready(function () {
508 $(\''.(dol_escape_js(preg_match('/^\./', $htmlname) ? $htmlname : '#'.$htmlname)).'\').'.$tmpplugin.'({
509 dir: \'ltr\',';
510 if (preg_match('/onrightofpage/', $morecss)) { // when $morecss contains 'onrightofpage', the select2 component must also be inside a parent with class="parentonrightofpage"
511 $msg .= ' dropdownAutoWidth: true, dropdownParent: $(\'#'.$htmlname.'\').parent(), '."\n";
512 }
513 $msg .= ' width: \''.dol_escape_js($widthTypeOfAutocomplete).'\', /* off or resolve */
514 minimumInputLength: '.((int) $minLengthToAutocomplete).',
515 language: (typeof select2arrayoflanguage === \'undefined\') ? \'en\' : select2arrayoflanguage,
516 matcher: function (params, data) {
517 if ($.trim(params.term) === "") {
518 return data;
519 }
520 keywords = (params.term).split(" ");
521 for (var i = 0; i < keywords.length; i++) {
522 if (((data.text).toUpperCase()).indexOf((keywords[i]).toUpperCase()) == -1) {
523 return null;
524 }
525 }
526 return data;
527 },
528 theme: \'default'.dol_escape_js($moreselect2theme).'\', /* to add css on generated html components */
529 containerCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
530 selectionCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
531 dropdownCssClass: \'ui-dialog\',
532 templateResult: function (data, container) { /* Format visible output into combo list */
533 /* Code to add class of origin OPTION propagated to the new select2 <li> tag */
534 if (data.element) { $(container).addClass($(data.element).attr("class")); }
535 //console.log("data html is "+$(data.element).attr("data-html"));
536 if (data.id == \''.(dol_escape_js($idforemptyvalue)).'\' && $(data.element).attr("data-html") == undefined) {
537 return \'&nbsp;\';
538 }
539 if ($(data.element).attr("data-html") != undefined) {
540 /* If property html set, we decode html entities and use this. */
541 /* Note that HTML content must have been sanitized from js with dol_escape_htmltag(xxx, 0, 0, \'\', 0, 1) when building the select option. */
542 if (typeof htmlEntityDecodeJs === "function") {
543 return htmlEntityDecodeJs($(data.element).attr("data-html"));
544 }
545 }
546 return data.text;
547 },
548 templateSelection: function (selection) { /* Format visible output of selected value */
549 if (selection.id == \''.(dol_escape_js($idforemptyvalue)).'\') return \'<span class="placeholder">\'+selection.text+\'</span>\';
550 return selection.text;
551 },
552 escapeMarkup: function(markup) {
553 return markup;
554 }
555 })';
556 if ($forcefocus) {
557 $msg .= '.select2(\'focus\')';
558 }
559 $msg .= ';'."\n";
560
561 $msg .= '});'."\n";
562 $msg .= "</script>\n";
563
564 $msg .= ajax_event($htmlname, $events);
565
566 return $msg;
567}
568
569
578function ajax_event($htmlname, $events)
579{
580 $out = '';
581
582 if (is_array($events) && count($events)) { // If an array of js events to do were provided.
583 $out = '<!-- JS code to manage event for id = ' . $htmlname . ' -->
584 <script>
585 $(document).ready(function () {
586 jQuery("#'.$htmlname.'").change(function () {
587 var obj = '.json_encode($events) . ';
588 $.each(obj, function(key,values) {
589 if (values.method.length) {
590 runJsCodeForEvent'.$htmlname.'(values);
591 }
592 });
593 });
594 function runJsCodeForEvent'.$htmlname.'(obj) {
595 var id = $("#'.$htmlname.'").val();
596 var method = obj.method;
597 var url = obj.url;
598 var htmlname = obj.htmlname;
599 var showempty = obj.showempty;
600 console.log("Run runJsCodeForEvent-'.$htmlname.' from ajax_combobox id="+id+" method="+method+" showempty="+showempty+" url="+url+" htmlname="+htmlname);
601 $.getJSON(url,
602 {
603 action: method,
604 id: id,
605 htmlname: htmlname,
606 showempty: showempty
607 },
608 function(response) {
609 $.each(obj.params, function(key,action) {
610 if (key.length) {
611 var num = response.num;
612 if (num > 0) {
613 $("#" + key).removeAttr(action);
614 } else {
615 $("#" + key).attr(action, action);
616 }
617 }
618 });
619
620 console.log("Replace HTML content of select#"+htmlname);
621 $("select#" + htmlname).html(response.value);
622 if (response.num) {
623 var selecthtml_str = response.value; /* response.value is the HTML string with list of options */
624 var selecthtml_dom=$.parseHTML(selecthtml_str);
625 if (typeof(selecthtml_dom[0][0]) !== \'undefined\') {
626 $("#inputautocomplete"+htmlname).val(selecthtml_dom[0][0].innerHTML);
627 }
628 } else {
629 $("#inputautocomplete"+htmlname).val("");
630 }
631 $("select#" + htmlname).change(); /* Trigger event change */
632 }
633 );
634 }
635 });
636 </script>';
637 }
638
639 return $out;
640}
641
642
663function ajax_constantonoff($code, $input = array(), $entity = null, $revertonoff = 0, $strict = 0, $forcereload = 0, $marginleftonlyshort = 2, $forcenoajax = 0, $setzeroinsteadofdel = 0, $suffix = '', $mode = '', $morecss = 'inline-block', $userconst = 0, $showwarning = '')
664{
665 global $conf, $langs, $user, $db;
666
667 $entity = ((isset($entity) && is_numeric($entity) && $entity >= 0) ? $entity : $conf->entity);
668 if (!isset($input)) {
669 $input = array();
670 }
671
672 if (empty($conf->use_javascript_ajax) || $forcenoajax) {
673 if (!getDolGlobalString($code)) {
674 $out = '<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>';
675 } else {
676 $out = '<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>';
677 }
678 } else {
679 $userconstid = 0;
680 if (is_object($userconst)) {
681 $userconstid = $userconst->id;
682 } elseif (is_numeric($userconst) && $userconst > 0) {
683 $userconstid = $userconst;
684 $userconst = new User($db);
685 $userconst->fetch($userconstid);
686 }
687
688 $out = "\n<!-- Ajax code to switch constant ".$code." -->".'
689 <script>
690 $(document).ready(function() {
691 var input = '.json_encode($input).';
692 var url = \''.DOL_URL_ROOT.'/core/ajax/constantonoff.php\';
693 var code = \''.dol_escape_js($code).'\';
694 var entity = \''.dol_escape_js((string) $entity).'\';
695 var strict = \''.dol_escape_js((string) $strict).'\';
696 var userid = \''.dol_escape_js((string) $user->id).'\';
697 var userconst = '.((int) $userconstid).';
698 var yesButton = \''.dol_escape_js($langs->transnoentities("Yes")).'\';
699 var noButton = \''.dol_escape_js($langs->transnoentities("No")).'\';
700 var token = \''.currentToken().'\';
701 var warning = \''.dol_escape_js($showwarning).'\';
702
703 // Set constant
704 $("#set_" + code).click(function() {
705 if (warning) {
706 alert(warning);
707 }
708
709 if (input.alert && input.alert.set) {
710 if (input.alert.set.yesButton) yesButton = input.alert.set.yesButton;
711 if (input.alert.set.noButton) noButton = input.alert.set.noButton;
712 confirmConstantAction("set", url, code, input, input.alert.set, entity, yesButton, noButton, strict, userid, token);
713 } else {
714 setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token, 1, userconst);
715 }
716 });
717
718 // Del constant
719 $("#del_" + code).click(function() {
720 if (input.alert && input.alert.del) {
721 if (input.alert.del.yesButton) yesButton = input.alert.del.yesButton;
722 if (input.alert.del.noButton) noButton = input.alert.del.noButton;
723 confirmConstantAction("del", url, code, input, input.alert.del, entity, yesButton, noButton, strict, userid, token);
724 } else {';
725 if (empty($setzeroinsteadofdel)) {
726 $out .= ' delConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token, userconst);';
727 } else {
728 $out .= ' setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token, 0, userconst);';
729 }
730 $out .= ' }
731 });
732 });
733 </script>'."\n";
734
735 if (!empty($userconst) && $userconst instanceof User) {
736 $value = getDolUserString($code, '', $userconst);
737 } else {
738 $value = getDolGlobalString($code);
739 }
740 $out .= '<div id="confirm_'.$code.'" title="" style="display: none;"></div>';
741 $out .= '<span id="set_'.$code.'" class="valignmiddle inline-block linkobject '.($value ? 'hideobject' : '').($morecss ? ' '.$morecss : '').'">'.($revertonoff ? img_picto($langs->trans("Enabled"), 'switch_on', '', 0, 0, 0, '', '', $marginleftonlyshort) : img_picto($langs->trans("Disabled"), 'switch_off', '', 0, 0, 0, '', '', $marginleftonlyshort)).'</span>';
742 $out .= '<span id="del_'.$code.'" class="valignmiddle inline-block linkobject '.($value ? '' : 'hideobject').($morecss ? ' '.$morecss : '').'">'.($revertonoff ? img_picto($langs->trans("Disabled"), 'switch_off'.$suffix, '', 0, 0, 0, '', '', $marginleftonlyshort) : img_picto($langs->trans("Enabled"), 'switch_on'.$suffix, '', 0, 0, 0, '', '', $marginleftonlyshort)).'</span>';
743 $out .= "\n";
744 }
745
746 return $out;
747}
748
766function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input = array(), $morecss = '', $htmlname = '', $forcenojs = 0, $moreparam = '')
767{
768 global $conf, $langs;
769
770 if (empty($htmlname)) {
771 $htmlname = $code;
772 }
773
774 $out = '';
775
776 if (!empty($conf->use_javascript_ajax) && empty($forcenojs)) {
777 $out .= '<script>
778 $(function() {
779 var input = '.json_encode($input).';
780
781 // Set constant
782 $("#set_'.$htmlname.'_'.$object->id.'").click(function() {
783 console.log("Click managed by ajax_object_onoff");
784 $.get( "'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
785 action: \'set\',
786 field: \''.dol_escape_js($field).'\',
787 value: \'1\',
788 element: \''.dol_escape_js((empty($object->module) || $object->module == $object->element) ? $object->element : $object->element.'@'.$object->module).'\',
789 id: \''.((int) $object->id).'\',
790 token: \''.currentToken().'\'
791 },
792 function() {
793 $("#set_'.$htmlname.'_'.$object->id.'").hide();
794 $("#del_'.$htmlname.'_'.$object->id.'").show();
795 // Enable another element
796 if (input.disabled && input.disabled.length > 0) {
797 $.each(input.disabled, function(key,value) {
798 $("#" + value).removeAttr("disabled");
799 if ($("#" + value).hasClass("butActionRefused") == true) {
800 $("#" + value).removeClass("butActionRefused");
801 $("#" + value).addClass("butAction");
802 }
803 });
804 // Show another element
805 } else if (input.showhide && input.showhide.length > 0) {
806 $.each(input.showhide, function(key,value) {
807 $("#" + value).show();
808 });
809 }
810 });
811 });
812
813 // Del constant
814 $("#del_'.$htmlname.'_'.$object->id.'").click(function() {
815 console.log("Click managed by ajax_object_onoff");
816 $.get( "'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
817 action: \'set\',
818 field: \''.dol_escape_js($field).'\',
819 value: \'0\',
820 element: \''.dol_escape_js((empty($object->module) || $object->module == $object->element) ? $object->element : $object->element.'@'.$object->module).'\',
821 id: \''.((int) $object->id).'\',
822 token: \''.currentToken().'\'
823 },
824 function() {
825 $("#del_'.$htmlname.'_'.$object->id.'").hide();
826 $("#set_'.$htmlname.'_'.$object->id.'").show();
827 // Disable another element
828 if (input.disabled && input.disabled.length > 0) {
829 $.each(input.disabled, function(key,value) {
830 $("#" + value).prop("disabled", true);
831 if ($("#" + value).hasClass("butAction") == true) {
832 $("#" + value).removeClass("butAction");
833 $("#" + value).addClass("butActionRefused");
834 }
835 });
836 // Hide another element
837 } else if (input.showhide && input.showhide.length > 0) {
838 $.each(input.showhide, function(key,value) {
839 $("#" + value).hide();
840 });
841 }
842 });
843 });
844 });
845 </script>';
846 }
847
848 $switchon = 'switch_on';
849 $switchoff = 'switch_off';
850 $cssswitchon = '';
851 $cssswitchoff = '';
852 $tmparray = explode(':', $text_on);
853 if (!empty($tmparray[1])) {
854 $text_on = $tmparray[0];
855 $switchon = $tmparray[1];
856 if (!empty($tmparray[2])) {
857 $cssswitchon = $tmparray[2];
858 }
859 }
860 $tmparray = explode(':', $text_off);
861 if (!empty($tmparray[1])) {
862 $text_off = $tmparray[0];
863 $switchoff = $tmparray[1];
864 if (!empty($tmparray[2])) {
865 $cssswitchoff = $tmparray[2];
866 }
867 }
868
869 if (empty($conf->use_javascript_ajax) || $forcenojs) {
870 $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.($moreparam ? '&'.$moreparam : '')).'">'.img_picto($langs->trans($text_off), $switchoff, '', 0, 0, 0, '', $cssswitchoff).'</a>';
871 $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.($moreparam ? '&'.$moreparam : '')).'">'.img_picto($langs->trans($text_on), $switchon, '', 0, 0, 0, '', $cssswitchon).'</a>';
872 } else {
873 $out .= '<span id="set_'.$htmlname.'_'.$object->id.'" class="linkobject '.($object->$code == 1 ? 'hideobject' : '').($morecss ? ' '.$morecss : '').'">'.img_picto($langs->trans($text_off), $switchoff, '', 0, 0, 0, '', $cssswitchoff).'</span>';
874 $out .= '<span id="del_'.$htmlname.'_'.$object->id.'" class="linkobject '.($object->$code == 1 ? '' : 'hideobject').($morecss ? ' '.$morecss : '').'">'.img_picto($langs->trans($text_on), $switchon, '', 0, 0, 0, '', $cssswitchon).'</span>';
875 }
876
877 return $out;
878}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
ajax_autocompleter($selected, $htmlname, $url, $urloption='', $minLength=2, $autoselect=0, $ajaxoptions=array(), $moreparams='')
Generic function that return javascript to add to transform a common input text or select field into ...
Definition ajax.lib.php:49
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:475
ajax_dialog($title, $message, $w=350, $h=150)
Show an ajax dialog.
Definition ajax.lib.php:432
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 text field into ...
Definition ajax.lib.php:324
ajax_event($htmlname, $events)
Add event management script.
Definition ajax.lib.php:578
Class to manage Dolibarr users.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
currentToken()
Return the value of token currently saved into session with name 'token'.
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.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79