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