47function ajax_autocompleter($selected, $htmlname, $url, $urloption =
'', $minLength = 2, $autoselect = 0, $ajaxoptions = array(), $moreparams =
'')
51 if (empty($minLength)) {
55 $dataforrenderITem =
'ui-autocomplete';
56 $dataforitem =
'ui-autocomplete-item';
58 if (defined(
'JS_QUERY_AUTOCOMPLETE_RENDERITEM')) {
59 $dataforrenderITem = constant(
'JS_QUERY_AUTOCOMPLETE_RENDERITEM');
61 if (defined(
'JS_QUERY_AUTOCOMPLETE_ITEM')) {
62 $dataforitem = constant(
'JS_QUERY_AUTOCOMPLETE_ITEM');
65 $htmlnamejquery = str_replace(
'.',
'\\\\.', $htmlname);
69 $script =
'<input type="hidden" name="'.$htmlname.
'" id="'.$htmlname.
'" value="'.$selected.
'" '.($moreparams ? $moreparams :
'').
' />';
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 */
77 /* Remove selected id as soon as we type or delete a char (it means old selection is wrong). Use keyup/down instead of change to avoid loosing the product id. This is needed only for select of predefined product */
78 $("input#search_'.$htmlnamejquery.
'").keydown(function(e) {
79 if (e.keyCode != 9) /* If not "Tab" key */
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("");
87 // Check options for secondary actions when keyup
88 $("input#search_'.$htmlnamejquery.
'").keyup(function() {
89 if ($(this).val().length == 0)
91 $("#search_'.$htmlnamejquery.
'").val("");
92 $("#'.$htmlnamejquery.
'").val("").trigger("change");
93 if (options.option_disabled) {
94 $("#" + options.option_disabled).removeAttr("disabled");
96 if (options.disabled) {
97 $.each(options.disabled, function(key, value) {
98 $("#" + value).removeAttr("disabled");
101 if (options.update) {
102 $.each(options.update, function(key, value) {
103 $("#" + key).val("").trigger("change");
107 $.each(options.show, function(key, value) {
108 $("#" + value).hide().trigger("hide");
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("");
116 $("#" + key).html("");
123 $("input#search_'.$htmlnamejquery.
'").autocomplete({
124 source: function( request, response ) {
125 $.get("'.$url.($urloption ?
'?'.$urloption :
'').
'", { "'.str_replace(
'.',
'_', $htmlname).
'": request.term }, function(data){
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");
134 if (item.label != null) {
135 label = item.label.toString();
138 if (options.update) {
139 $.each(options.update, function(key, value) {
140 update[key] = item[value];
144 if (options.update_textarea) {
145 $.each(options.update_textarea, function(key, value) {
146 textarea[key] = item[value];
150 console.log("Return value from GET to the rest of code");
151 return { label: label,
154 disabled: item.disabled,
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,
167 if (isModEnabled(
'multicurrency')) {
169 multicurrency_code: item.multicurrency_code,
170 multicurrency_unitprice: item.multicurrency_unitprice,
174 description : item.description,
175 ref_customer: item.ref_customer,
177 default_vat_code: item.default_vat_code
181 console.error("Error: Ajax url '.$url.($urloption ?
'?'.$urloption :
'').
' has returned an empty page. Should be an empty json array.");
186 minLength: '.((
int) $minLength).
',
187 select: function( event, ui ) { // Function ran once new value has been selected into javascript combo
188 console.log("We will trigger change on input '.$htmlname.
' because of the select definition of autocomplete code for input#search_'.$htmlname.
'");
189 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");
191 console.log("Propagate before some properties retrieved by ajax into data-xxx properties of #'.$htmlnamejquery.
' component");
192 //console.log(ui.item);
194 // For supplier price and customer when price by quantity is off
195 $("#'.$htmlnamejquery.
'").attr("data-up", ui.item.price_ht);
196 $("#'.$htmlnamejquery.
'").attr("data-up-locale", ui.item.price_unit_ht_locale);
197 $("#'.$htmlnamejquery.
'").attr("data-base", ui.item.pricebasetype);
198 $("#'.$htmlnamejquery.
'").attr("data-qty", ui.item.qty);
199 $("#'.$htmlnamejquery.
'").attr("data-discount", ui.item.discount);
200 $("#'.$htmlnamejquery.
'").attr("data-description", ui.item.description);
201 $("#'.$htmlnamejquery.
'").attr("data-ref-customer", ui.item.ref_customer);
202 $("#'.$htmlnamejquery.
'").attr("data-tvatx", ui.item.tva_tx);
203 $("#'.$htmlnamejquery.
'").attr("data-default-vat-code", ui.item.default_vat_code);
205 if (isModEnabled(
'multicurrency')) {
207 // For multi-currency values
208 $("#'.$htmlnamejquery.
'").attr("data-multicurrency-code", ui.item.multicurrency_code);
209 $("#'.$htmlnamejquery.
'").attr("data-multicurrency-unitprice", ui.item.multicurrency_unitprice);
214 // For customer price when PRODUIT_CUSTOMER_PRICES_BY_QTY is on
215 console.log("PRODUIT_CUSTOMER_PRICES_BY_QTY is on, propagate also prices by quantity into data-pbqxxx properties");
216 $("#'.$htmlnamejquery.
'").attr("data-pbq", ui.item.pbq);
217 $("#'.$htmlnamejquery.
'").attr("data-pbqup", ui.item.price_ht);
218 $("#'.$htmlnamejquery.
'").attr("data-pbqbase", ui.item.pricebasetype);
219 $("#'.$htmlnamejquery.
'").attr("data-pbqqty", ui.item.qty);
220 $("#'.$htmlnamejquery.
'").attr("data-pbqpercent", ui.item.discount);
224 // A new value has been selected, we trigger the handlers on #htmlnamejquery
225 console.log("Trigger changes on #'.$htmlnamejquery.
'");
226 $("#'.$htmlnamejquery.
'").val(ui.item.id).trigger("change"); // Select new value
228 // Complementary actions
230 // Disable an element
231 if (options.option_disabled) {
232 console.log("Make action option_disabled on #"+options.option_disabled+" with disabled="+ui.item.disabled)
233 if (ui.item.disabled) {
234 $("#" + options.option_disabled).prop("disabled", true);
236 $.jnotify(options.error, "error", true); // Output with jnotify the error message
238 if (options.warning) {
239 $.jnotify(options.warning, "warning", false); // Output with jnotify the warning message
242 $("#" + options.option_disabled).removeAttr("disabled");
246 if (options.disabled) {
247 console.log("Make action disabled on each "+options.option_disabled)
248 $.each(options.disabled, function(key, value) {
249 $("#" + value).prop("disabled", true);
253 console.log("Make action show on each "+options.show)
254 $.each(options.show, function(key, value) {
255 $("#" + value).show().trigger("show");
260 if (ui.item.update) {
261 console.log("Make action update on each ui.item.update (if there is)")
262 // loop on each "update" fields
263 $.each(ui.item.update, function(key, value) {
264 console.log("Set value "+value+" into #"+key);
265 $("#" + key).val(value).trigger("change");
268 if (ui.item.textarea) {
269 console.log("Make action textarea on each ui.item.textarea (if there is)")
270 $.each(ui.item.textarea, function(key, value) {
271 if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances[key] != "undefined") {
272 CKEDITOR.instances[key].setData(value);
273 CKEDITOR.instances[key].focus();
275 $("#" + key).html(value);
276 $("#" + key).focus();
280 console.log("ajax_autocompleter new value selected, we trigger change also on original component so on field #search_'.$htmlname.
'");
282 $("#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.
285 }).data("'.$dataforrenderITem.
'")._renderItem = function( ul, item ) {
287 .data( "'.$dataforitem.
'", item ) // jQuery UI > 1.10.0
288 .append( \'<a><span class="tag">\' + item.label + "</span></a>" )
293 $script .=
'</script>';
464function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = 0, $forcefocus = 0, $widthTypeOfAutocomplete =
'resolve', $idforemptyvalue =
'-1', $morecss =
'')
469 if (!empty($conf->browser->layout) && $conf->browser->layout ==
'phone' && !empty($conf->global->MAIN_DISALLOW_SELECT2_WITH_SMARTPHONE)) {
473 if (!empty($conf->global->MAIN_DISABLE_AJAX_COMBOX)) {
476 if (empty($conf->use_javascript_ajax)) {
479 if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && !defined(
'REQUIRE_JQUERY_MULTISELECT')) {
482 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
486 if (empty($minLengthToAutocomplete)) {
487 $minLengthToAutocomplete = 0;
490 $moreselect2theme = ($morecss ?
dol_escape_js(
' '.$morecss) :
'');
491 $moreselect2theme = preg_replace(
'/widthcentpercentminus[^\s]*/',
'', $moreselect2theme);
493 $tmpplugin =
'select2';
494 $msg =
"\n".
'<!-- JS CODE TO ENABLE '.$tmpplugin.
' for id = '.$htmlname.
' -->
496 $(document).ready(function () {
497 $(\''.(preg_match(
'/^\./', $htmlname) ? $htmlname :
'#'.$htmlname).
'\').
'.$tmpplugin.'({
499 if (preg_match(
'/onrightofpage/', $morecss)) {
500 $msg .=
' dropdownAutoWidth: true, dropdownParent: $(\'#'.$htmlname.
'\').parent(),
'."\n";
502 $msg .= ' width: \
''.dol_escape_js($widthTypeOfAutocomplete).
'\',
503 minimumInputLength:
'.((int) $minLengthToAutocomplete).',
504 language: select2arrayoflanguage,
505 matcher:
function (params, data) {
506 if ($.trim(params.term) ===
"") {
509 keywords = (params.term).split(
" ");
510 for (var i = 0; i < keywords.length; i++) {
511 if (((data.text).toUpperCase()).indexOf((keywords[i]).toUpperCase()) == -1) {
517 theme: \
'default'.$moreselect2theme.
'\',
518 containerCssClass: \
':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
519 selectionCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
520 dropdownCssClass: \'ui-dialog\',
521 templateResult: function (data, container) { /* Format visible output into combo list */
522 /* Code to add class of origin OPTION propagated to the new select2 <li> tag */
523 if (data.element) { $(container).addClass($(data.element).attr("class")); }
524 //console.log("data html is "+$(data.element).attr("data-html"));
525 if (data.id == '.((int) $idforemptyvalue).
' && $(data.element).attr("data-html") == undefined) {
528 if ($(data.element).attr("data-html") != undefined) {
529 /* If property html set, we decode html entities and use this. */
530 /* Note that HTML content must have been sanitized from js with dol_escape_htmltag(xxx, 0, 0, \'\', 0, 1) when building the select option. */
531 return htmlEntityDecodeJs($(data.element).attr("data-html"));
535 templateSelection: function (selection) { /* Format visible output of selected value */
536 if (selection.id == '.((int) $idforemptyvalue).
') return \'<span class="placeholder">\'+selection.text+\'</span>\';
537 return selection.text;
539 escapeMarkup: function(markup) {
544 $msg .=
'.select2(\'focus\')';
549 $msg .=
"</script>\n";
645function ajax_constantonoff($code, $input = array(), $entity =
null, $revertonoff = 0, $strict = 0, $forcereload = 0, $marginleftonlyshort = 2, $forcenoajax = 0, $setzeroinsteadofdel = 0, $suffix =
'', $mode =
'', $morecss =
'')
647 global $conf, $langs, $user;
649 $entity = ((isset($entity) && is_numeric($entity) && $entity >= 0) ? $entity : $conf->entity);
650 if (!isset($input)) {
654 if (empty($conf->use_javascript_ajax) || $forcenoajax) {
655 if (empty($conf->global->$code)) {
656 print
'<a '.($morecss ?
'class="'.$morecss.
'" ' :
'').
'href="'.$_SERVER[
'PHP_SELF'].
'?action=set_'.$code.
'&token='.newToken().
'&entity='.$entity.($mode ?
'&mode='.$mode :
'').($forcereload ?
'&dol_resetcache=1' :
'').
'">'.
img_picto($langs->trans(
"Disabled"),
'off').
'</a>';
658 print
'<a '.($morecss ?
'class="'.$morecss.
'" ' :
'').
' href="'.$_SERVER[
'PHP_SELF'].
'?action=del_'.$code.
'&token='.newToken().
'&entity='.$entity.($mode ?
'&mode='.$mode :
'').($forcereload ?
'&dol_resetcache=1' :
'').
'">'.
img_picto($langs->trans(
"Enabled"),
'on').
'</a>';
661 $out =
"\n<!-- Ajax code to switch constant ".$code.
" -->".
'
663 $(document).ready(function() {
664 var input = '.json_encode($input).
';
665 var url = \''.DOL_URL_ROOT.
'/core/ajax/constantonoff.php\';
667 var entity = \
''.dol_escape_js($entity).
'\';
668 var strict = \
''.dol_escape_js($strict).
'\';
669 var userid = \
''.dol_escape_js($user->id).
'\';
670 var yesButton = \
''.dol_escape_js($langs->transnoentities(
"Yes")).
'\';
671 var noButton = \
''.dol_escape_js($langs->transnoentities(
"No")).
'\';
672 var token = \
''.currentToken().
'\';
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);
681 setConstant(url, code, input, entity, 0,
'.((int) $forcereload).', userid, token);
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);
692 if (empty($setzeroinsteadofdel)) {
693 $out .=' delConstant(url, code, input, entity, 0,
'.((int) $forcereload).', userid, token);
';
695 $out .=' setConstant(url, code, input, entity, 0,
'.((int) $forcereload).', userid, token, 0);
';
702 $out .= '<div
id=
"confirm_'.$code.'" title=
"" style=
"display: none;"></div>
';
703 $out .= '<span
id=
"set_'.$code.'" class=
"valignmiddle linkobject '.(!empty($conf->global->$code) ? 'hideobject' : '').'">
'.($revertonoff ?img_picto($langs->trans("Enabled"), 'switch_on
', '', false, 0, 0, '', '', $marginleftonlyshort) : img_picto($langs->trans("Disabled"), 'switch_off
', '', false, 0, 0, '', '', $marginleftonlyshort)).'</span>
';
704 $out .= '<span
id=
"del_'.$code.'" class=
"valignmiddle linkobject '.(!empty($conf->global->$code) ? '' : 'hideobject').'">
'.($revertonoff ?img_picto($langs->trans("Disabled"), 'switch_off
'.$suffix, '', false, 0, 0, '', '', $marginleftonlyshort) : img_picto($langs->trans("Enabled"), 'switch_on
'.$suffix, '', false, 0, 0, '', '', $marginleftonlyshort)).'</span>
';
726function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input = array(), $morecss = '
', $htmlname = '', $forcenojs = 0)
728 global $conf, $langs;
730 if (empty($htmlname)) {
733 //var_dump($object->module); var_dump($object->element);
737 if (!empty($conf->use_javascript_ajax)) {
740 var input =
'.json_encode($input).';
743 $(
"#set_'.$htmlname.'_'.$object->id.'").click(
function() {
744 console.log(
"Click managed by ajax_object_onoff");
745 $.get(
"'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
747 field: \''.dol_escape_js($field).
'\',
749 element: \''.dol_escape_js((empty($object->module) || $object->module == $object->element) ? $object->element : $object->element.
'@'.$object->module).
'\',
750 id: \
''.((int) $object->id).
'\',
751 token: \
''.currentToken().
'\'
754 $(
"#set_'.$htmlname.'_'.$object->id.'").hide();
755 $(
"#del_'.$htmlname.'_'.$object->id.'").show();
757 if (input.disabled && input.disabled.length > 0) {
758 $.each(input.disabled,
function(key,value) {
759 $(
"#" + value).removeAttr(
"disabled");
760 if ($(
"#" + value).hasClass(
"butActionRefused") == true) {
761 $(
"#" + value).removeClass(
"butActionRefused");
762 $(
"#" + value).addClass(
"butAction");
766 }
else if (input.showhide && input.showhide.length > 0) {
767 $.each(input.showhide,
function(key,value) {
768 $(
"#" + value).show();
775 $(
"#del_'.$htmlname.'_'.$object->id.'").click(
function() {
776 console.log(
"Click managed by ajax_object_onoff");
777 $.get(
"'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
779 field: \''.dol_escape_js($field).
'\',
781 element: \''.
dol_escape_js((empty($object->module) || $object->module == $object->element) ? $object->element : $object->element.
'@'.$object->module).
'\',
782 id: \''.((int) $object->id).
'\',
786 $("#del_'.$htmlname.
'_'.$object->id.
'").hide();
787 $("#set_'.$htmlname.
'_'.$object->id.
'").show();
788 // Disable another element
789 if (input.disabled && input.disabled.length > 0) {
790 $.each(input.disabled, function(key,value) {
791 $("#" + value).prop("disabled", true);
792 if ($("#" + value).hasClass("butAction") == true) {
793 $("#" + value).removeClass("butAction");
794 $("#" + value).addClass("butActionRefused");
797 // Hide another element
798 } else if (input.showhide && input.showhide.length > 0) {
799 $.each(input.showhide, function(key,value) {
800 $("#" + value).hide();
809 $switchon =
'switch_on';
810 $switchoff =
'switch_off';
813 $tmparray = explode(
':', $text_on);
814 if (!empty($tmparray[1])) {
815 $text_on = $tmparray[0];
816 $switchon = $tmparray[1];
817 if (!empty($tmparray[2])) {
818 $cssswitchon = $tmparray[2];
821 $tmparray = explode(
':', $text_off);
822 if (!empty($tmparray[1])) {
823 $text_off = $tmparray[0];
824 $switchoff = $tmparray[1];
825 if (!empty($tmparray[2])) {
826 $cssswitchoff = $tmparray[2];
830 if (empty($conf->use_javascript_ajax) || $forcenojs) {
831 $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>';
832 $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>';
834 $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>';
835 $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>';
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...
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
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...
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)