dolibarr 21.0.0-alpha
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 MDW <mdeweerd@users.noreply.github.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 * or see https://www.gnu.org/
20 */
21
48function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLength = 2, $autoselect = 0, $ajaxoptions = array(), $moreparams = '')
49{
50 if (empty($minLength)) {
51 $minLength = 1;
52 }
53
54 $dataforrenderITem = 'ui-autocomplete';
55 $dataforitem = 'ui-autocomplete-item';
56 // Allow two constant to use other values for backward compatibility
57 if (defined('JS_QUERY_AUTOCOMPLETE_RENDERITEM')) {
58 $dataforrenderITem = constant('JS_QUERY_AUTOCOMPLETE_RENDERITEM');
59 }
60 if (defined('JS_QUERY_AUTOCOMPLETE_ITEM')) {
61 $dataforitem = constant('JS_QUERY_AUTOCOMPLETE_ITEM');
62 }
63
64 $htmlnamejquery = str_replace('.', '\\\\.', $htmlname);
65
66 // Input search_htmlname is original field
67 // Input htmlname is a second input field used when using ajax autocomplete.
68 $script = '<input type="hidden" name="'.$htmlname.'" id="'.$htmlname.'" value="'.$selected.'" '.($moreparams ? $moreparams : '').' />';
69
70 $script .= '<!-- Javascript code for autocomplete of field '.$htmlname.' -->'."\n";
71 $script .= '<script>'."\n";
72 $script .= '$(document).ready(function() {
73 var autoselect = '.((int) $autoselect).';
74 var options = '.json_encode($ajaxoptions).'; /* Option of actions to do after keyup, or after select */
75
76 /* 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 */
77 $("input#search_'.$htmlnamejquery.'").keydown(function(e) {
78 if (e.keyCode != 9) /* If not "Tab" key */
79 {
80 if (e.keyCode == 13) { return false; } /* disable "ENTER" key useful for barcode readers */
81 console.log("Clear id previously selected for field '.$htmlname.'");
82 $("#'.$htmlnamejquery.'").val("");
83 }
84 });
85
86 // Check options for secondary actions when keyup
87 $("input#search_'.$htmlnamejquery.'").keyup(function() {
88 if ($(this).val().length == 0)
89 {
90 $("#search_'.$htmlnamejquery.'").val("");
91 $("#'.$htmlnamejquery.'").val("").trigger("change");
92 if (options.option_disabled) {
93 $("#" + options.option_disabled).removeAttr("disabled");
94 }
95 if (options.disabled) {
96 $.each(options.disabled, function(key, value) {
97 $("#" + value).removeAttr("disabled");
98 });
99 }
100 if (options.update) {
101 $.each(options.update, function(key, value) {
102 $("#" + key).val("").trigger("change");
103 });
104 }
105 if (options.show) {
106 $.each(options.show, function(key, value) {
107 $("#" + value).hide().trigger("hide");
108 });
109 }
110 if (options.update_textarea) {
111 $.each(options.update_textarea, function(key, value) {
112 if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances[key] != "undefined") {
113 CKEDITOR.instances[key].setData("");
114 } else {
115 $("#" + key).html("");
116 }
117 });
118 }
119 }
120 });
121
122 // Activate the autocomplete to execute the GET
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 multicurrency_code: item.multicurrency_code,
167 multicurrency_unitprice: item.multicurrency_unitprice,
168 description : item.description,
169 ref_customer: item.ref_customer,
170 tva_tx: item.tva_tx,
171 default_vat_code: item.default_vat_code,
172 supplier_ref: item.supplier_ref
173 }
174 }));
175 } else {
176 console.error("Error: Ajax url '.$url.($urloption ? '?'.$urloption : '').' has returned an empty page. Should be an empty json array.");
177 }
178 }, "json");
179 },
180 dataType: "json",
181 minLength: '.((int) $minLength).',
182 select: function( event, ui ) { // Function ran once a new value has been selected into the javascript combo
183 console.log("We will trigger change on input '.$htmlname.' because of the select definition of autocomplete code for input#search_'.$htmlname.'");
184 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");
185
186 console.log("Before, we propagate some properties, retrieved by the ajax of the get, into the data-xxx properties of the component #'.$htmlnamejquery.'");
187 //console.log(ui.item);
188
189 // For supplier price and customer when price by quantity is off
190 $("#'.$htmlnamejquery.'").attr("data-up", ui.item.price_ht);
191 $("#'.$htmlnamejquery.'").attr("data-up-locale", ui.item.price_unit_ht_locale);
192 $("#'.$htmlnamejquery.'").attr("data-base", ui.item.pricebasetype);
193 $("#'.$htmlnamejquery.'").attr("data-qty", ui.item.qty);
194 $("#'.$htmlnamejquery.'").attr("data-discount", ui.item.discount);
195 $("#'.$htmlnamejquery.'").attr("data-description", ui.item.description);
196 $("#'.$htmlnamejquery.'").attr("data-ref-customer", ui.item.ref_customer);
197 $("#'.$htmlnamejquery.'").attr("data-tvatx", ui.item.tva_tx);
198 $("#'.$htmlnamejquery.'").attr("data-default-vat-code", ui.item.default_vat_code);
199 $("#'.$htmlnamejquery.'").attr("data-supplier-ref", ui.item.supplier_ref); // supplier_ref of price
200
201 // For multi-currency values
202 $("#'.$htmlnamejquery.'").attr("data-multicurrency-code", ui.item.multicurrency_code);
203 $("#'.$htmlnamejquery.'").attr("data-multicurrency-unitprice", ui.item.multicurrency_unitprice);
204 ';
205 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) {
206 $script .= '
207 // For customer price when PRODUIT_CUSTOMER_PRICES_BY_QTY is on
208 console.log("PRODUIT_CUSTOMER_PRICES_BY_QTY is on, so we propagate also prices by quantity into data-pbqxxx properties");
209 $("#'.$htmlnamejquery.'").attr("data-pbq", ui.item.pbq);
210 $("#'.$htmlnamejquery.'").attr("data-pbqup", ui.item.price_ht);
211 $("#'.$htmlnamejquery.'").attr("data-pbqbase", ui.item.pricebasetype);
212 $("#'.$htmlnamejquery.'").attr("data-pbqqty", ui.item.qty);
213 $("#'.$htmlnamejquery.'").attr("data-pbqpercent", ui.item.discount);
214 ';
215 }
216 $script .= '
217 // A new value has been selected, we trigger the handlers on #htmlnamejquery
218 console.log("Now, we trigger changes on #'.$htmlnamejquery.'");
219 $("#'.$htmlnamejquery.'").val(ui.item.id).trigger("change"); // Select new value
220
221 // Complementary actions
222
223 // Disable an element
224 if (options.option_disabled) {
225 console.log("Make action option_disabled on #"+options.option_disabled+" with disabled="+ui.item.disabled)
226 if (ui.item.disabled) {
227 $("#" + options.option_disabled).prop("disabled", true);
228 if (options.error) {
229 $.jnotify(options.error, "error", true); // Output with jnotify the error message
230 }
231 if (options.warning) {
232 $.jnotify(options.warning, "warning", false); // Output with jnotify the warning message
233 }
234 } else {
235 $("#" + options.option_disabled).removeAttr("disabled");
236 }
237 }
238
239 if (options.disabled) {
240 console.log("Make action \'disabled\' on each "+options.option_disabled)
241 $.each(options.disabled, function(key, value) {
242 $("#" + value).prop("disabled", true);
243 });
244 }
245 if (options.show) {
246 console.log("Make action \'show\' on each "+options.show)
247 $.each(options.show, function(key, value) {
248 $("#" + value).show().trigger("show");
249 });
250 }
251
252 // Update an input
253 if (ui.item.update) {
254 console.log("Make action \'update\' on each ui.item.update (if there is)")
255 // loop on each "update" fields
256 $.each(ui.item.update, function(key, value) {
257 console.log("Set value "+value+" into #"+key);
258 $("#" + key).val(value).trigger("change");
259 });
260 }
261 if (ui.item.textarea) {
262 console.log("Make action \'textarea\' on each ui.item.textarea (if there is)")
263 $.each(ui.item.textarea, function(key, value) {
264 if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances[key] != "undefined") {
265 CKEDITOR.instances[key].setData(value);
266 CKEDITOR.instances[key].focus();
267 } else {
268 $("#" + key).html(value);
269 $("#" + key).focus();
270 }
271 });
272 }
273 console.log("ajax_autocompleter new value selected, we trigger change also on original component so on field #search_'.$htmlname.'");
274
275 $("#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.
276 }
277 ,delay: 500
278 }).data("'.$dataforrenderITem.'")._renderItem = function( ul, item ) {
279 return $("<li>")
280 .data( "'.$dataforitem.'", item ) // jQuery UI > 1.10.0
281 .append( \'<a><span class="tag">\' + item.label + "</span></a>" )
282 .appendTo(ul);
283 };
284
285 });';
286 $script .= '</script>';
287
288 return $script;
289}
290
305function ajax_multiautocompleter($htmlname, $fields, $url, $option = '', $minLength = 2, $autoselect = 0)
306{
307 $script = '<!-- Autocomplete -->'."\n";
308 $script .= '<script>';
309 $script .= 'jQuery(document).ready(function() {
310 var fields = '.json_encode($fields).';
311 var nboffields = fields.length;
312 var autoselect = '.$autoselect.';
313 //alert(fields + " " + nboffields);
314
315 // Activate the autocomplete to execute the GET
316 jQuery("input#'.$htmlname.'").autocomplete({
317 dataType: "json",
318 minLength: '.$minLength.',
319 source: function( request, response ) {
320 jQuery.getJSON( "'.$url.($option ? '?'.$option : '').'", { '.$htmlname.': request.term }, function(data){
321 response( jQuery.map( data, function( item ) {
322 if (autoselect == 1 && data.length == 1) {
323 jQuery("#'.$htmlname.'").val(item.value);
324 // TODO move this to specific request
325 if (item.states) {
326 jQuery("#state_id").html(item.states);
327 }
328 for (i=0;i<nboffields;i++) {
329 if (item[fields[i]]) { // If defined
330 //alert(item[fields[i]]);
331 jQuery("#" + fields[i]).val(item[fields[i]]);
332 }
333 }
334 }
335 return item
336 }));
337 });
338 },
339 select: function( event, ui ) {
340 needtotrigger = "";
341 for (i=0;i<nboffields;i++) {
342 //alert(fields[i] + " = " + ui.item[fields[i]]);
343 if (fields[i]=="selectcountry_id")
344 {
345 if (ui.item[fields[i]] > 0) // Do not erase country if unknown
346 {
347 oldvalue=jQuery("#" + fields[i]).val();
348 newvalue=ui.item[fields[i]];
349 //alert(oldvalue+" "+newvalue);
350 jQuery("#" + fields[i]).val(ui.item[fields[i]]);
351 if (oldvalue != newvalue) // To force select2 to refresh visible content
352 {
353 needtotrigger="#" + fields[i];
354 }
355
356 // If we set new country and new state, we need to set a new list of state to allow change
357 if (ui.item.states && ui.item["state_id"] != jQuery("#state_id").value) {
358 jQuery("#state_id").html(ui.item.states);
359 }
360 }
361 }
362 else if (fields[i]=="state_id" || fields[i]=="state_id")
363 {
364 if (ui.item[fields[i]] > 0) // Do not erase state 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]]); // This may fails if not correct country
370 if (oldvalue != newvalue) // To force select2 to refresh visible content
371 {
372 needtotrigger="#" + fields[i];
373 }
374 }
375 }
376 else if (ui.item[fields[i]]) { // If defined
377 oldvalue=jQuery("#" + fields[i]).val();
378 newvalue=ui.item[fields[i]];
379 //alert(oldvalue+" "+newvalue);
380 jQuery("#" + fields[i]).val(ui.item[fields[i]]);
381 if (oldvalue != newvalue) // To force select2 to refresh visible content
382 {
383 needtotrigger="#" + fields[i];
384 }
385 }
386
387 if (needtotrigger != "") // To force select2 to refresh visible content
388 {
389 // 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
390 // This is required for example when changing zip with autocomplete that change the country
391 jQuery(needtotrigger).delay(500).queue(function() {
392 jQuery(this).trigger("change");
393 });
394 }
395 }
396 }
397 });
398 });';
399 $script .= '</script>';
400
401 return $script;
402}
403
413function ajax_dialog($title, $message, $w = 350, $h = 150)
414{
415 $newtitle = dol_textishtml($title) ? dol_string_nohtmltag($title, 1) : $title;
416 $msg = '<div id="dialog-info" title="'.dol_escape_htmltag($newtitle).'">';
417 $msg .= $message;
418 $msg .= '</div>'."\n";
419 $msg .= '<script>
420 jQuery(function() {
421 jQuery("#dialog-info").dialog({
422 resizable: false,
423 height:'.$h.',
424 width:'.$w.',
425 modal: true,
426 buttons: {
427 Ok: function() {
428 jQuery(this).dialog(\'close\');
429 }
430 }
431 });
432 });
433 </script>';
434
435 $msg .= "\n";
436
437 return $msg;
438}
439
440
456function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = 0, $forcefocus = 0, $widthTypeOfAutocomplete = 'resolve', $idforemptyvalue = '-1', $morecss = '')
457{
458 global $conf;
459
460 // select2 can be disabled for smartphones
461 if (!empty($conf->browser->layout) && $conf->browser->layout == 'phone' && getDolGlobalString('MAIN_DISALLOW_SELECT2_WITH_SMARTPHONE')) {
462 return '';
463 }
464
465 if (getDolGlobalString('MAIN_DISABLE_AJAX_COMBOX')) {
466 return '';
467 }
468 if (empty($conf->use_javascript_ajax)) {
469 return '';
470 }
471 if (!getDolGlobalString('MAIN_USE_JQUERY_MULTISELECT') && !defined('REQUIRE_JQUERY_MULTISELECT')) {
472 return '';
473 }
474 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
475 return '';
476 }
477
478 if (empty($minLengthToAutocomplete)) {
479 $minLengthToAutocomplete = 0;
480 }
481
482 $moreselect2theme = ($morecss ? dol_escape_js(' '.$morecss) : '');
483 $moreselect2theme = preg_replace('/widthcentpercentminus[^\s]*/', '', $moreselect2theme);
484
485 $tmpplugin = 'select2';
486 $msg = "\n".'<!-- JS CODE TO ENABLE '.$tmpplugin.' for id = '.$htmlname.' -->
487 <script>
488 $(document).ready(function () {
489 $(\''.(preg_match('/^\./', $htmlname) ? $htmlname : '#'.$htmlname).'\').'.$tmpplugin.'({
490 dir: \'ltr\',';
491 if (preg_match('/onrightofpage/', $morecss)) { // when $morecss contains 'onrightofpage', the select2 component must also be inside a parent with class="parentonrightofpage"
492 $msg .= ' dropdownAutoWidth: true, dropdownParent: $(\'#'.$htmlname.'\').parent(), '."\n";
493 }
494 $msg .= ' width: \''.dol_escape_js($widthTypeOfAutocomplete).'\', /* off or resolve */
495 minimumInputLength: '.((int) $minLengthToAutocomplete).',
496 language: select2arrayoflanguage,
497 matcher: function (params, data) {
498 if ($.trim(params.term) === "") {
499 return data;
500 }
501 keywords = (params.term).split(" ");
502 for (var i = 0; i < keywords.length; i++) {
503 if (((data.text).toUpperCase()).indexOf((keywords[i]).toUpperCase()) == -1) {
504 return null;
505 }
506 }
507 return data;
508 },
509 theme: \'default'.$moreselect2theme.'\', /* to add css on generated html components */
510 containerCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
511 selectionCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
512 dropdownCssClass: \'ui-dialog\',
513 templateResult: function (data, container) { /* Format visible output into combo list */
514 /* Code to add class of origin OPTION propagated to the new select2 <li> tag */
515 if (data.element) { $(container).addClass($(data.element).attr("class")); }
516 //console.log("data html is "+$(data.element).attr("data-html"));
517 if (data.id == '.((int) $idforemptyvalue).' && $(data.element).attr("data-html") == undefined) {
518 return \'&nbsp;\';
519 }
520 if ($(data.element).attr("data-html") != undefined) {
521 /* If property html set, we decode html entities and use this. */
522 /* Note that HTML content must have been sanitized from js with dol_escape_htmltag(xxx, 0, 0, \'\', 0, 1) when building the select option. */
523 if (typeof htmlEntityDecodeJs === "function") {
524 return htmlEntityDecodeJs($(data.element).attr("data-html"));
525 }
526 }
527 return data.text;
528 },
529 templateSelection: function (selection) { /* Format visible output of selected value */
530 if (selection.id == '.((int) $idforemptyvalue).') return \'<span class="placeholder">\'+selection.text+\'</span>\';
531 return selection.text;
532 },
533 escapeMarkup: function(markup) {
534 return markup;
535 }
536 })';
537 if ($forcefocus) {
538 $msg .= '.select2(\'focus\')';
539 }
540 $msg .= ';'."\n";
541
542 $msg .= '});'."\n";
543 $msg .= "</script>\n";
544
545 $msg .= ajax_event($htmlname, $events);
546
547 return $msg;
548}
549
550
559function ajax_event($htmlname, $events)
560{
561 $out = '';
562
563 if (is_array($events) && count($events)) { // If an array of js events to do were provided.
564 $out = '<!-- JS code to manage event for id = ' . $htmlname . ' -->
565 <script>
566 $(document).ready(function () {
567 jQuery("#'.$htmlname.'").change(function () {
568 var obj = '.json_encode($events) . ';
569 $.each(obj, function(key,values) {
570 if (values.method.length) {
571 runJsCodeForEvent'.$htmlname.'(values);
572 }
573 });
574 });
575 function runJsCodeForEvent'.$htmlname.'(obj) {
576 var id = $("#'.$htmlname.'").val();
577 var method = obj.method;
578 var url = obj.url;
579 var htmlname = obj.htmlname;
580 var showempty = obj.showempty;
581 console.log("Run runJsCodeForEvent-'.$htmlname.' from ajax_combobox id="+id+" method="+method+" showempty="+showempty+" url="+url+" htmlname="+htmlname);
582 $.getJSON(url,
583 {
584 action: method,
585 id: id,
586 htmlname: htmlname,
587 showempty: showempty
588 },
589 function(response) {
590 $.each(obj.params, function(key,action) {
591 if (key.length) {
592 var num = response.num;
593 if (num > 0) {
594 $("#" + key).removeAttr(action);
595 } else {
596 $("#" + key).attr(action, action);
597 }
598 }
599 });
600
601 console.log("Replace HTML content of select#"+htmlname);
602 $("select#" + htmlname).html(response.value);
603 if (response.num) {
604 var selecthtml_str = response.value; /* response.value is the HTML string with list of options */
605 var selecthtml_dom=$.parseHTML(selecthtml_str);
606 if (typeof(selecthtml_dom[0][0]) !== \'undefined\') {
607 $("#inputautocomplete"+htmlname).val(selecthtml_dom[0][0].innerHTML);
608 }
609 } else {
610 $("#inputautocomplete"+htmlname).val("");
611 }
612 $("select#" + htmlname).change(); /* Trigger event change */
613 }
614 );
615 }
616 });
617 </script>';
618 }
619
620 return $out;
621}
622
623
642function ajax_constantonoff($code, $input = array(), $entity = null, $revertonoff = 0, $strict = 0, $forcereload = 0, $marginleftonlyshort = 2, $forcenoajax = 0, $setzeroinsteadofdel = 0, $suffix = '', $mode = '', $morecss = 'inline-block')
643{
644 global $conf, $langs, $user;
645
646 $entity = ((isset($entity) && is_numeric($entity) && $entity >= 0) ? $entity : $conf->entity);
647 if (!isset($input)) {
648 $input = array();
649 }
650
651 if (empty($conf->use_javascript_ajax) || $forcenoajax) {
652 if (empty($conf->global->$code)) {
653 $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>';
654 } else {
655 $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>';
656 }
657 } else {
658 $out = "\n<!-- Ajax code to switch constant ".$code." -->".'
659 <script>
660 $(document).ready(function() {
661 var input = '.json_encode($input).';
662 var url = \''.DOL_URL_ROOT.'/core/ajax/constantonoff.php\';
663 var code = \''.dol_escape_js($code).'\';
664 var entity = \''.dol_escape_js($entity).'\';
665 var strict = \''.dol_escape_js($strict).'\';
666 var userid = \''.dol_escape_js($user->id).'\';
667 var yesButton = \''.dol_escape_js($langs->transnoentities("Yes")).'\';
668 var noButton = \''.dol_escape_js($langs->transnoentities("No")).'\';
669 var token = \''.currentToken().'\';
670
671 // Set constant
672 $("#set_" + code).click(function() {
673 if (input.alert && input.alert.set) {
674 if (input.alert.set.yesButton) yesButton = input.alert.set.yesButton;
675 if (input.alert.set.noButton) noButton = input.alert.set.noButton;
676 confirmConstantAction("set", url, code, input, input.alert.set, entity, yesButton, noButton, strict, userid, token);
677 } else {
678 setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token);
679 }
680 });
681
682 // Del constant
683 $("#del_" + code).click(function() {
684 if (input.alert && input.alert.del) {
685 if (input.alert.del.yesButton) yesButton = input.alert.del.yesButton;
686 if (input.alert.del.noButton) noButton = input.alert.del.noButton;
687 confirmConstantAction("del", url, code, input, input.alert.del, entity, yesButton, noButton, strict, userid, token);
688 } else {';
689 if (empty($setzeroinsteadofdel)) {
690 $out .= ' delConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token);';
691 } else {
692 $out .= ' setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token, 0);';
693 }
694 $out .= ' }
695 });
696 });
697 </script>'."\n";
698
699 $out .= '<div id="confirm_'.$code.'" title="" style="display: none;"></div>';
700 $out .= '<span id="set_'.$code.'" class="valignmiddle inline-block linkobject '.(getDolGlobalString($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>';
701 $out .= '<span id="del_'.$code.'" class="valignmiddle inline-block linkobject '.(getDolGlobalString($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>';
702 $out .= "\n";
703 }
704
705 return $out;
706}
707
724function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input = array(), $morecss = '', $htmlname = '', $forcenojs = 0)
725{
726 global $conf, $langs;
727
728 if (empty($htmlname)) {
729 $htmlname = $code;
730 }
731 //var_dump($object->module); var_dump($object->element);
732
733 $out = '';
734
735 if (!empty($conf->use_javascript_ajax) && empty($forcenojs)) {
736 $out .= '<script>
737 $(function() {
738 var input = '.json_encode($input).';
739
740 // Set constant
741 $("#set_'.$htmlname.'_'.$object->id.'").click(function() {
742 console.log("Click managed by ajax_object_onoff");
743 $.get( "'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
744 action: \'set\',
745 field: \''.dol_escape_js($field).'\',
746 value: \'1\',
747 element: \''.dol_escape_js((empty($object->module) || $object->module == $object->element) ? $object->element : $object->element.'@'.$object->module).'\',
748 id: \''.((int) $object->id).'\',
749 token: \''.currentToken().'\'
750 },
751 function() {
752 $("#set_'.$htmlname.'_'.$object->id.'").hide();
753 $("#del_'.$htmlname.'_'.$object->id.'").show();
754 // Enable another element
755 if (input.disabled && input.disabled.length > 0) {
756 $.each(input.disabled, function(key,value) {
757 $("#" + value).removeAttr("disabled");
758 if ($("#" + value).hasClass("butActionRefused") == true) {
759 $("#" + value).removeClass("butActionRefused");
760 $("#" + value).addClass("butAction");
761 }
762 });
763 // Show another element
764 } else if (input.showhide && input.showhide.length > 0) {
765 $.each(input.showhide, function(key,value) {
766 $("#" + value).show();
767 });
768 }
769 });
770 });
771
772 // Del constant
773 $("#del_'.$htmlname.'_'.$object->id.'").click(function() {
774 console.log("Click managed by ajax_object_onoff");
775 $.get( "'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
776 action: \'set\',
777 field: \''.dol_escape_js($field).'\',
778 value: \'0\',
779 element: \''.dol_escape_js((empty($object->module) || $object->module == $object->element) ? $object->element : $object->element.'@'.$object->module).'\',
780 id: \''.((int) $object->id).'\',
781 token: \''.currentToken().'\'
782 },
783 function() {
784 $("#del_'.$htmlname.'_'.$object->id.'").hide();
785 $("#set_'.$htmlname.'_'.$object->id.'").show();
786 // Disable another element
787 if (input.disabled && input.disabled.length > 0) {
788 $.each(input.disabled, function(key,value) {
789 $("#" + value).prop("disabled", true);
790 if ($("#" + value).hasClass("butAction") == true) {
791 $("#" + value).removeClass("butAction");
792 $("#" + value).addClass("butActionRefused");
793 }
794 });
795 // Hide another element
796 } else if (input.showhide && input.showhide.length > 0) {
797 $.each(input.showhide, function(key,value) {
798 $("#" + value).hide();
799 });
800 }
801 });
802 });
803 });
804 </script>';
805 }
806
807 $switchon = 'switch_on';
808 $switchoff = 'switch_off';
809 $cssswitchon = '';
810 $cssswitchoff = '';
811 $tmparray = explode(':', $text_on);
812 if (!empty($tmparray[1])) {
813 $text_on = $tmparray[0];
814 $switchon = $tmparray[1];
815 if (!empty($tmparray[2])) {
816 $cssswitchon = $tmparray[2];
817 }
818 }
819 $tmparray = explode(':', $text_off);
820 if (!empty($tmparray[1])) {
821 $text_off = $tmparray[0];
822 $switchoff = $tmparray[1];
823 if (!empty($tmparray[2])) {
824 $cssswitchoff = $tmparray[2];
825 }
826 }
827
828 if (empty($conf->use_javascript_ajax) || $forcenojs) {
829 $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>';
830 $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>';
831 } else {
832 $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>';
833 $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>';
834 }
835
836 return $out;
837}
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:58
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:48
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:456
ajax_dialog($title, $message, $w=350, $h=150)
Show an ajax dialog.
Definition ajax.lib.php:413
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:305
ajax_event($htmlname, $events)
Add event management script.
Definition ajax.lib.php:559
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
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.
dol_textishtml($msg, $option=0)
Return if a text is a html content.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.