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 * 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 if (autoselect == 1 && data.length == 1) {
131 $("#search_'.$htmlnamejquery.'").val(item.value);
132 $("#'.$htmlnamejquery.'").val(item.key).trigger("change");
133 }
134 var label = "";
135 if (item.label != null) {
136 label = item.label.toString();
137 }
138 var update = {};
139 if (options.update) {
140 $.each(options.update, function(key, value) {
141 update[key] = item[value];
142 });
143 }
144 var textarea = {};
145 if (options.update_textarea) {
146 $.each(options.update_textarea, function(key, value) {
147 textarea[key] = item[value];
148 });
149 }
150
151 console.log("Return value from GET to the rest of code");
152 return { label: label,
153 value: item.value,
154 id: item.key,
155 disabled: item.disabled,
156 update: update,
157 textarea: textarea,
158 pbq: item.pbq,
159 type: item.type,
160 qty: item.qty,
161 discount: item.discount,
162 pricebasetype: item.pricebasetype,
163 price_ht: item.price_ht,
164 price_ttc: item.price_ttc,
165 price_unit_ht: item.price_unit_ht,
166 price_unit_ht_locale: item.price_unit_ht_locale,
167 multicurrency_code: item.multicurrency_code,
168 multicurrency_unitprice: item.multicurrency_unitprice,
169 description : item.description,
170 ref_customer: item.ref_customer,
171 tva_tx: item.tva_tx,
172 default_vat_code: item.default_vat_code,
173 supplier_ref: item.supplier_ref
174 }
175 }));
176 } else {
177 console.error("Error: Ajax url '.$url.($urloption ? '?'.$urloption : '').' has returned an empty page. Should be an empty json array.");
178 }
179 }, "json");
180 },
181 dataType: "json",
182 minLength: '.((int) $minLength).',
183 select: function( event, ui ) { // Function ran once a new value has been selected into the javascript combo
184 console.log("We will trigger change on input '.$htmlname.' because of the select definition of autocomplete code for input#search_'.$htmlname.'");
185 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");
186
187 console.log("Before, we propagate some properties, retrieved by the ajax of the get, into the data-xxx properties of the component #'.$htmlnamejquery.'");
188 //console.log(ui.item);
189
190 // For supplier price and customer when price by quantity is off
191 $("#'.$htmlnamejquery.'").attr("data-up", ui.item.price_ht);
192 $("#'.$htmlnamejquery.'").attr("data-up-locale", ui.item.price_unit_ht_locale);
193 $("#'.$htmlnamejquery.'").attr("data-base", ui.item.pricebasetype);
194 $("#'.$htmlnamejquery.'").attr("data-qty", ui.item.qty);
195 $("#'.$htmlnamejquery.'").attr("data-discount", ui.item.discount);
196 $("#'.$htmlnamejquery.'").attr("data-description", ui.item.description);
197 $("#'.$htmlnamejquery.'").attr("data-ref-customer", ui.item.ref_customer);
198 $("#'.$htmlnamejquery.'").attr("data-tvatx", ui.item.tva_tx);
199 $("#'.$htmlnamejquery.'").attr("data-default-vat-code", ui.item.default_vat_code);
200 $("#'.$htmlnamejquery.'").attr("data-supplier-ref", ui.item.supplier_ref); // supplier_ref of price
201
202 // For multi-currency values
203 $("#'.$htmlnamejquery.'").attr("data-multicurrency-code", ui.item.multicurrency_code);
204 $("#'.$htmlnamejquery.'").attr("data-multicurrency-unitprice", ui.item.multicurrency_unitprice);
205 ';
206 if (getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY') || getDolGlobalString('PRODUIT_CUSTOMER_PRICES_BY_QTY_MULTIPRICES')) {
207 $script .= '
208 // For customer price when PRODUIT_CUSTOMER_PRICES_BY_QTY is on
209 console.log("PRODUIT_CUSTOMER_PRICES_BY_QTY is on, so we propagate also prices by quantity into data-pbqxxx properties");
210 $("#'.$htmlnamejquery.'").attr("data-pbq", ui.item.pbq);
211 $("#'.$htmlnamejquery.'").attr("data-pbqup", ui.item.price_ht);
212 $("#'.$htmlnamejquery.'").attr("data-pbqbase", ui.item.pricebasetype);
213 $("#'.$htmlnamejquery.'").attr("data-pbqqty", ui.item.qty);
214 $("#'.$htmlnamejquery.'").attr("data-pbqpercent", ui.item.discount);
215 ';
216 }
217 $script .= '
218 // A new value has been selected, we trigger the handlers on #htmlnamejquery
219 console.log("Now, we trigger changes on #'.$htmlnamejquery.'");
220 $("#'.$htmlnamejquery.'").val(ui.item.id).trigger("change"); // Select new value
221
222 // Complementary actions
223
224 // Disable an element
225 if (options.option_disabled) {
226 console.log("Make action option_disabled on #"+options.option_disabled+" with disabled="+ui.item.disabled)
227 if (ui.item.disabled) {
228 $("#" + options.option_disabled).prop("disabled", true);
229 if (options.error) {
230 $.jnotify(options.error, "error", true); // Output with jnotify the error message
231 }
232 if (options.warning) {
233 $.jnotify(options.warning, "warning", false); // Output with jnotify the warning message
234 }
235 } else {
236 $("#" + options.option_disabled).removeAttr("disabled");
237 }
238 }
239
240 if (options.disabled) {
241 console.log("Make action \'disabled\' on each "+options.option_disabled)
242 $.each(options.disabled, function(key, value) {
243 $("#" + value).prop("disabled", true);
244 });
245 }
246 if (options.show) {
247 console.log("Make action \'show\' on each "+options.show)
248 $.each(options.show, function(key, value) {
249 $("#" + value).show().trigger("show");
250 });
251 }
252
253 // Update an input
254 if (ui.item.update) {
255 console.log("Make action \'update\' on each ui.item.update (if there is)")
256 // loop on each "update" fields
257 $.each(ui.item.update, function(key, value) {
258 console.log("Set value "+value+" into #"+key);
259 $("#" + key).val(value).trigger("change");
260 });
261 }
262 if (ui.item.textarea) {
263 console.log("Make action \'textarea\' on each ui.item.textarea (if there is)")
264 $.each(ui.item.textarea, function(key, value) {
265 if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances[key] != "undefined") {
266 CKEDITOR.instances[key].setData(value);
267 CKEDITOR.instances[key].focus();
268 } else {
269 $("#" + key).html(value);
270 $("#" + key).focus();
271 }
272 });
273 }
274 console.log("ajax_autocompleter new value selected, we trigger change also on original component so on field #search_'.$htmlname.'");
275
276 $("#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.
277 }
278 ,delay: 500
279 }).data("'.$dataforrenderITem.'")._renderItem = function( ul, item ) {
280 return $("<li>")
281 .data( "'.$dataforitem.'", item ) // jQuery UI > 1.10.0
282 .append( \'<a><span class="tag">\' + item.label + "</span></a>" )
283 .appendTo(ul);
284 };
285
286 });';
287 $script .= '</script>';
288
289 return $script;
290}
291
306function ajax_multiautocompleter($htmlname, $fields, $url, $option = '', $minLength = 2, $autoselect = 0)
307{
308 $script = '<!-- Autocomplete -->'."\n";
309 $script .= '<script>';
310 $script .= 'jQuery(document).ready(function() {
311 var fields = '.json_encode($fields).';
312 var nboffields = fields.length;
313 var autoselect = '.$autoselect.';
314 //alert(fields + " " + nboffields);
315
316 // Activate the autocomplete to execute the GET
317 jQuery("input#'.$htmlname.'").autocomplete({
318 dataType: "json",
319 minLength: '.$minLength.',
320 source: function( request, response ) {
321 jQuery.getJSON( "'.$url.($option ? '?'.$option : '').'", { '.$htmlname.': request.term }, function(data){
322 response( jQuery.map( data, function( item ) {
323 if (autoselect == 1 && data.length == 1) {
324 jQuery("#'.$htmlname.'").val(item.value);
325 // TODO move this to specific request
326 if (item.states) {
327 jQuery("#state_id").html(item.states);
328 }
329 for (i=0;i<nboffields;i++) {
330 if (item[fields[i]]) { // If defined
331 //alert(item[fields[i]]);
332 jQuery("#" + fields[i]).val(item[fields[i]]);
333 }
334 }
335 }
336 return item
337 }));
338 });
339 },
340 select: function( event, ui ) {
341 needtotrigger = "";
342 for (i=0;i<nboffields;i++) {
343 //alert(fields[i] + " = " + ui.item[fields[i]]);
344 if (fields[i]=="selectcountry_id")
345 {
346 if (ui.item[fields[i]] > 0) // Do not erase country if unknown
347 {
348 oldvalue=jQuery("#" + fields[i]).val();
349 newvalue=ui.item[fields[i]];
350 //alert(oldvalue+" "+newvalue);
351 jQuery("#" + fields[i]).val(ui.item[fields[i]]);
352 if (oldvalue != newvalue) // To force select2 to refresh visible content
353 {
354 needtotrigger="#" + fields[i];
355 }
356
357 // If we set new country and new state, we need to set a new list of state to allow change
358 if (ui.item.states && ui.item["state_id"] != jQuery("#state_id").value) {
359 jQuery("#state_id").html(ui.item.states);
360 }
361 }
362 }
363 else if (fields[i]=="state_id" || fields[i]=="state_id")
364 {
365 if (ui.item[fields[i]] > 0) // Do not erase state if unknown
366 {
367 oldvalue=jQuery("#" + fields[i]).val();
368 newvalue=ui.item[fields[i]];
369 //alert(oldvalue+" "+newvalue);
370 jQuery("#" + fields[i]).val(ui.item[fields[i]]); // This may fails if not correct country
371 if (oldvalue != newvalue) // To force select2 to refresh visible content
372 {
373 needtotrigger="#" + fields[i];
374 }
375 }
376 }
377 else if (ui.item[fields[i]]) { // If defined
378 oldvalue=jQuery("#" + fields[i]).val();
379 newvalue=ui.item[fields[i]];
380 //alert(oldvalue+" "+newvalue);
381 jQuery("#" + fields[i]).val(ui.item[fields[i]]);
382 if (oldvalue != newvalue) // To force select2 to refresh visible content
383 {
384 needtotrigger="#" + fields[i];
385 }
386 }
387
388 if (needtotrigger != "") // To force select2 to refresh visible content
389 {
390 // 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
391 // This is required for example when changing zip with autocomplete that change the country
392 jQuery(needtotrigger).delay(500).queue(function() {
393 jQuery(this).trigger("change");
394 });
395 }
396 }
397 }
398 });
399 });';
400 $script .= '</script>';
401
402 return $script;
403}
404
414function ajax_dialog($title, $message, $w = 350, $h = 150)
415{
416 $newtitle = dol_textishtml($title) ? dol_string_nohtmltag($title, 1) : $title;
417 $msg = '<div id="dialog-info" title="'.dol_escape_htmltag($newtitle).'">';
418 $msg .= $message;
419 $msg .= '</div>'."\n";
420 $msg .= '<script>
421 jQuery(function() {
422 jQuery("#dialog-info").dialog({
423 resizable: false,
424 height:'.$h.',
425 width:'.$w.',
426 modal: true,
427 buttons: {
428 Ok: function() {
429 jQuery(this).dialog(\'close\');
430 }
431 }
432 });
433 });
434 </script>';
435
436 $msg .= "\n";
437
438 return $msg;
439}
440
441
457function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = 0, $forcefocus = 0, $widthTypeOfAutocomplete = 'resolve', $idforemptyvalue = '-1', $morecss = '')
458{
459 global $conf;
460
461 // select2 can be disabled for smartphones
462 if (!empty($conf->browser->layout) && $conf->browser->layout == 'phone' && getDolGlobalString('MAIN_DISALLOW_SELECT2_WITH_SMARTPHONE')) {
463 return '';
464 }
465
466 if (getDolGlobalString('MAIN_DISABLE_AJAX_COMBOX')) {
467 return '';
468 }
469 if (empty($conf->use_javascript_ajax)) {
470 return '';
471 }
472 if (!getDolGlobalString('MAIN_USE_JQUERY_MULTISELECT') && !defined('REQUIRE_JQUERY_MULTISELECT')) {
473 return '';
474 }
475 if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) {
476 return '';
477 }
478
479 if (empty($minLengthToAutocomplete)) {
480 $minLengthToAutocomplete = 0;
481 }
482
483 $moreselect2theme = ($morecss ? dol_escape_js(' '.$morecss) : '');
484 $moreselect2theme = preg_replace('/widthcentpercentminus[^\s]*/', '', $moreselect2theme);
485
486 $tmpplugin = 'select2';
487 $msg = "\n".'<!-- JS CODE TO ENABLE '.$tmpplugin.' for id = '.$htmlname.' -->
488 <script>
489 $(document).ready(function () {
490 $(\''.(preg_match('/^\./', $htmlname) ? $htmlname : '#'.$htmlname).'\').'.$tmpplugin.'({
491 dir: \'ltr\',';
492 if (preg_match('/onrightofpage/', $morecss)) { // when $morecss contains 'onrightofpage', the select2 component must also be inside a parent with class="parentonrightofpage"
493 $msg .= ' dropdownAutoWidth: true, dropdownParent: $(\'#'.$htmlname.'\').parent(), '."\n";
494 }
495 $msg .= ' width: \''.dol_escape_js($widthTypeOfAutocomplete).'\', /* off or resolve */
496 minimumInputLength: '.((int) $minLengthToAutocomplete).',
497 language: select2arrayoflanguage,
498 matcher: function (params, data) {
499 if ($.trim(params.term) === "") {
500 return data;
501 }
502 keywords = (params.term).split(" ");
503 for (var i = 0; i < keywords.length; i++) {
504 if (((data.text).toUpperCase()).indexOf((keywords[i]).toUpperCase()) == -1) {
505 return null;
506 }
507 }
508 return data;
509 },
510 theme: \'default'.$moreselect2theme.'\', /* to add css on generated html components */
511 containerCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
512 selectionCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
513 dropdownCssClass: \'ui-dialog\',
514 templateResult: function (data, container) { /* Format visible output into combo list */
515 /* Code to add class of origin OPTION propagated to the new select2 <li> tag */
516 if (data.element) { $(container).addClass($(data.element).attr("class")); }
517 //console.log("data html is "+$(data.element).attr("data-html"));
518 if (data.id == '.((int) $idforemptyvalue).' && $(data.element).attr("data-html") == undefined) {
519 return \'&nbsp;\';
520 }
521 if ($(data.element).attr("data-html") != undefined) {
522 /* If property html set, we decode html entities and use this. */
523 /* Note that HTML content must have been sanitized from js with dol_escape_htmltag(xxx, 0, 0, \'\', 0, 1) when building the select option. */
524 if (typeof htmlEntityDecodeJs === "function") {
525 return htmlEntityDecodeJs($(data.element).attr("data-html"));
526 }
527 }
528 return data.text;
529 },
530 templateSelection: function (selection) { /* Format visible output of selected value */
531 if (selection.id == '.((int) $idforemptyvalue).') return \'<span class="placeholder">\'+selection.text+\'</span>\';
532 return selection.text;
533 },
534 escapeMarkup: function(markup) {
535 return markup;
536 }
537 })';
538 if ($forcefocus) {
539 $msg .= '.select2(\'focus\')';
540 }
541 $msg .= ';'."\n";
542
543 $msg .= '});'."\n";
544 $msg .= "</script>\n";
545
546 $msg .= ajax_event($htmlname, $events);
547
548 return $msg;
549}
550
551
560function ajax_event($htmlname, $events)
561{
562 $out = '';
563
564 if (is_array($events) && count($events)) { // If an array of js events to do were provided.
565 $out = '<!-- JS code to manage event for id = ' . $htmlname . ' -->
566 <script>
567 $(document).ready(function () {
568 jQuery("#'.$htmlname.'").change(function () {
569 var obj = '.json_encode($events) . ';
570 $.each(obj, function(key,values) {
571 if (values.method.length) {
572 runJsCodeForEvent'.$htmlname.'(values);
573 }
574 });
575 });
576 function runJsCodeForEvent'.$htmlname.'(obj) {
577 var id = $("#'.$htmlname.'").val();
578 var method = obj.method;
579 var url = obj.url;
580 var htmlname = obj.htmlname;
581 var showempty = obj.showempty;
582 console.log("Run runJsCodeForEvent-'.$htmlname.' from ajax_combobox id="+id+" method="+method+" showempty="+showempty+" url="+url+" htmlname="+htmlname);
583 $.getJSON(url,
584 {
585 action: method,
586 id: id,
587 htmlname: htmlname,
588 showempty: showempty
589 },
590 function(response) {
591 $.each(obj.params, function(key,action) {
592 if (key.length) {
593 var num = response.num;
594 if (num > 0) {
595 $("#" + key).removeAttr(action);
596 } else {
597 $("#" + key).attr(action, action);
598 }
599 }
600 });
601
602 console.log("Replace HTML content of select#"+htmlname);
603 $("select#" + htmlname).html(response.value);
604 if (response.num) {
605 var selecthtml_str = response.value; /* response.value is the HTML string with list of options */
606 var selecthtml_dom=$.parseHTML(selecthtml_str);
607 if (typeof(selecthtml_dom[0][0]) !== \'undefined\') {
608 $("#inputautocomplete"+htmlname).val(selecthtml_dom[0][0].innerHTML);
609 }
610 } else {
611 $("#inputautocomplete"+htmlname).val("");
612 }
613 $("select#" + htmlname).change(); /* Trigger event change */
614 }
615 );
616 }
617 });
618 </script>';
619 }
620
621 return $out;
622}
623
624
644function 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)
645{
646 global $conf, $langs, $user;
647
648 $entity = ((isset($entity) && is_numeric($entity) && $entity >= 0) ? $entity : $conf->entity);
649 if (!isset($input)) {
650 $input = array();
651 }
652
653 if (empty($conf->use_javascript_ajax) || $forcenoajax) {
654 if (!getDolGlobalString($code)) {
655 $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>';
656 } else {
657 $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>';
658 }
659 } else {
660 $out = "\n<!-- Ajax code to switch constant ".$code." -->".'
661 <script>
662 $(document).ready(function() {
663 var input = '.json_encode($input).';
664 var url = \''.DOL_URL_ROOT.'/core/ajax/constantonoff.php\';
665 var code = \''.dol_escape_js($code).'\';
666 var entity = \''.dol_escape_js($entity).'\';
667 var strict = \''.dol_escape_js((string) $strict).'\';
668 var userid = \''.dol_escape_js((string) $user->id).'\';
669 var userconst = '.((int) $userconst).';
670 var yesButton = \''.dol_escape_js($langs->transnoentities("Yes")).'\';
671 var noButton = \''.dol_escape_js($langs->transnoentities("No")).'\';
672 var token = \''.currentToken().'\';
673
674 // Set constant
675 $("#set_" + code).click(function() {
676 if (input.alert && input.alert.set) {
677 if (input.alert.set.yesButton) yesButton = input.alert.set.yesButton;
678 if (input.alert.set.noButton) noButton = input.alert.set.noButton;
679 confirmConstantAction("set", url, code, input, input.alert.set, entity, yesButton, noButton, strict, userid, token);
680 } else {
681 setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token, 1, userconst);
682 }
683 });
684
685 // Del constant
686 $("#del_" + code).click(function() {
687 if (input.alert && input.alert.del) {
688 if (input.alert.del.yesButton) yesButton = input.alert.del.yesButton;
689 if (input.alert.del.noButton) noButton = input.alert.del.noButton;
690 confirmConstantAction("del", url, code, input, input.alert.del, entity, yesButton, noButton, strict, userid, token);
691 } else {';
692 if (empty($setzeroinsteadofdel)) {
693 $out .= ' delConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token, userconst);';
694 } else {
695 $out .= ' setConstant(url, code, input, entity, 0, '.((int) $forcereload).', userid, token, 0, userconst);';
696 }
697 $out .= ' }
698 });
699 });
700 </script>'."\n";
701
702 if ($userconst) {
703 $value = getDolUserString($code);
704 } else {
705 $value = getDolGlobalString($code);
706 }
707 $out .= '<div id="confirm_'.$code.'" title="" style="display: none;"></div>';
708 $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>';
709 $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>';
710 $out .= "\n";
711 }
712
713 return $out;
714}
715
733function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input = array(), $morecss = '', $htmlname = '', $forcenojs = 0, $moreparam = '')
734{
735 global $conf, $langs;
736
737 if (empty($htmlname)) {
738 $htmlname = $code;
739 }
740 //var_dump($object->module); var_dump($object->element);
741
742 $out = '';
743
744 if (!empty($conf->use_javascript_ajax) && empty($forcenojs)) {
745 $out .= '<script>
746 $(function() {
747 var input = '.json_encode($input).';
748
749 // Set constant
750 $("#set_'.$htmlname.'_'.$object->id.'").click(function() {
751 console.log("Click managed by ajax_object_onoff");
752 $.get( "'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
753 action: \'set\',
754 field: \''.dol_escape_js($field).'\',
755 value: \'1\',
756 element: \''.dol_escape_js((empty($object->module) || $object->module == $object->element) ? $object->element : $object->element.'@'.$object->module).'\',
757 id: \''.((int) $object->id).'\',
758 token: \''.currentToken().'\'
759 },
760 function() {
761 $("#set_'.$htmlname.'_'.$object->id.'").hide();
762 $("#del_'.$htmlname.'_'.$object->id.'").show();
763 // Enable another element
764 if (input.disabled && input.disabled.length > 0) {
765 $.each(input.disabled, function(key,value) {
766 $("#" + value).removeAttr("disabled");
767 if ($("#" + value).hasClass("butActionRefused") == true) {
768 $("#" + value).removeClass("butActionRefused");
769 $("#" + value).addClass("butAction");
770 }
771 });
772 // Show another element
773 } else if (input.showhide && input.showhide.length > 0) {
774 $.each(input.showhide, function(key,value) {
775 $("#" + value).show();
776 });
777 }
778 });
779 });
780
781 // Del constant
782 $("#del_'.$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: \'0\',
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 $("#del_'.$htmlname.'_'.$object->id.'").hide();
794 $("#set_'.$htmlname.'_'.$object->id.'").show();
795 // Disable another element
796 if (input.disabled && input.disabled.length > 0) {
797 $.each(input.disabled, function(key,value) {
798 $("#" + value).prop("disabled", true);
799 if ($("#" + value).hasClass("butAction") == true) {
800 $("#" + value).removeClass("butAction");
801 $("#" + value).addClass("butActionRefused");
802 }
803 });
804 // Hide another element
805 } else if (input.showhide && input.showhide.length > 0) {
806 $.each(input.showhide, function(key,value) {
807 $("#" + value).hide();
808 });
809 }
810 });
811 });
812 });
813 </script>';
814 }
815
816 $switchon = 'switch_on';
817 $switchoff = 'switch_off';
818 $cssswitchon = '';
819 $cssswitchoff = '';
820 $tmparray = explode(':', $text_on);
821 if (!empty($tmparray[1])) {
822 $text_on = $tmparray[0];
823 $switchon = $tmparray[1];
824 if (!empty($tmparray[2])) {
825 $cssswitchon = $tmparray[2];
826 }
827 }
828 $tmparray = explode(':', $text_off);
829 if (!empty($tmparray[1])) {
830 $text_off = $tmparray[0];
831 $switchoff = $tmparray[1];
832 if (!empty($tmparray[2])) {
833 $cssswitchoff = $tmparray[2];
834 }
835 }
836
837 if (empty($conf->use_javascript_ajax) || $forcenojs) {
838 $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>';
839 $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>';
840 } else {
841 $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>';
842 $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>';
843 }
844
845 return $out;
846}
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: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:457
ajax_dialog($title, $message, $w=350, $h=150)
Show an ajax dialog.
Definition ajax.lib.php:414
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:306
ajax_event($htmlname, $events)
Add event management script.
Definition ajax.lib.php:560
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.
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.