49function 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 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 */
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 // 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){
129 response($.map( data, function(item) {
130 console.log("Received answer from ajax GET, we populate array to return to the jquery autocomplete");
131 if (autoselect == 1 && data.length == 1) {
132 $("#search_'.$htmlnamejquery.
'").val(item.value);
133 $("#'.$htmlnamejquery.
'").val(item.key).trigger("change");
136 if (item.labelhtml != null) {
137 label = item.labelhtml.toString();
138 } else if (item.label != null) {
139 label = item.label.toString();
142 if (options.update) {
143 $.each(options.update, function(key, value) {
144 update[key] = item[value];
148 if (options.update_textarea) {
149 $.each(options.update_textarea, function(key, value) {
150 textarea[key] = item[value];
154 return { label: label,
157 disabled: item.disabled,
163 discount: item.discount,
164 pricebasetype: item.pricebasetype,
165 price_ht: item.price_ht,
166 price_ttc: item.price_ttc,
167 price_unit_ht: item.price_unit_ht,
168 price_unit_ht_locale: item.price_unit_ht_locale,
169 multicurrency_code: item.multicurrency_code,
170 multicurrency_unitprice: item.multicurrency_unitprice,
171 description : item.description,
172 ref_customer: item.ref_customer,
174 default_vat_code: item.default_vat_code,
175 supplier_ref: item.supplier_ref
179 console.error("Error: Ajax url '.$url.($urloption ?
'?'.$urloption :
'').
' has returned an empty page. Should be an empty json array.");
184 minLength: '.((
int) $minLength).
',
185 select: function( event, ui ) { // Function ran once a new value has been selected into the 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");
189 console.log("Before, we propagate some properties, retrieved by the ajax of the get, into the data-xxx properties of the component #'.$htmlnamejquery.
'");
190 //console.log(ui.item);
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 $("#'.$htmlnamejquery.
'").attr("data-supplier-ref", ui.item.supplier_ref); // supplier_ref of price
204 // For multi-currency values
205 $("#'.$htmlnamejquery.
'").attr("data-multicurrency-code", ui.item.multicurrency_code);
206 $("#'.$htmlnamejquery.
'").attr("data-multicurrency-unitprice", ui.item.multicurrency_unitprice);
210 // For customer price when PRODUIT_CUSTOMER_PRICES_BY_QTY is on
211 console.log("PRODUIT_CUSTOMER_PRICES_BY_QTY is on, so we propagate also prices by quantity into data-pbqxxx properties");
212 $("#'.$htmlnamejquery.
'").attr("data-pbq", ui.item.pbq);
213 $("#'.$htmlnamejquery.
'").attr("data-pbqup", ui.item.price_ht);
214 $("#'.$htmlnamejquery.
'").attr("data-pbqbase", ui.item.pricebasetype);
215 $("#'.$htmlnamejquery.
'").attr("data-pbqqty", ui.item.qty);
216 $("#'.$htmlnamejquery.
'").attr("data-pbqpercent", ui.item.discount);
220 // A new value has been selected, we trigger the handlers on #htmlnamejquery
221 console.log("Now, we trigger changes on #'.$htmlnamejquery.
'");
222 $("#'.$htmlnamejquery.
'").val(ui.item.id).trigger("change"); // Select new value
224 // Complementary actions
226 // Disable an element
227 if (options.option_disabled) {
228 console.log("Make action option_disabled on #"+options.option_disabled+" with disabled="+ui.item.disabled)
229 if (ui.item.disabled) {
230 $("#" + options.option_disabled).prop("disabled", true);
232 $.jnotify(options.error, "error", true); // Output with jnotify the error message
234 if (options.warning) {
235 $.jnotify(options.warning, "warning", false); // Output with jnotify the warning message
238 $("#" + options.option_disabled).removeAttr("disabled");
242 if (options.disabled) {
243 console.log("Make action \'disabled\' on each "+options.option_disabled)
244 $.each(options.disabled, function(key, value) {
245 $("#" + value).prop("disabled", true);
249 console.log("Make action \'show\' on each "+options.show)
250 $.each(options.show, function(key, value) {
251 $("#" + value).show().trigger("show");
256 if (ui.item.update) {
257 console.log("Make action \'update\' on each ui.item.update (if there is)")
258 // loop on each "update" fields
259 $.each(ui.item.update, function(key, value) {
260 console.log("Set value "+value+" into #"+key);
261 $("#" + key).val(value).trigger("change");
264 if (ui.item.textarea) {
265 console.log("Make action \'textarea\' on each ui.item.textarea (if there is)")
266 $.each(ui.item.textarea, function(key, value) {
267 if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances[key] != "undefined") {
268 CKEDITOR.instances[key].setData(value);
269 CKEDITOR.instances[key].focus();
271 $("#" + key).html(value);
272 $("#" + key).focus();
276 console.log("ajax_autocompleter new value selected, we trigger change also on original component so on field #search_'.$htmlname.
'");
278 $("#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.
282 const widgetData = $("input#search_'.$htmlnamejquery.
'").data("'.$dataforrenderITem.
'");
284 widgetData._renderItem = function( ul, item ) {
286 .data( "'.$dataforitem.
'", item ) // jQuery UI > 1.10.0
287 .append( \'<a><span class="tag">\' + item.label + "</span></a>" )
293 $script .=
'</script>';
463function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = 0, $forcefocus = 0, $widthTypeOfAutocomplete =
'resolve', $idforemptyvalue =
'-1', $morecss =
'')
468 if (!empty(
$conf->browser->layout) &&
$conf->browser->layout ==
'phone' &&
getDolGlobalString(
'MAIN_DISALLOW_SELECT2_WITH_SMARTPHONE')) {
475 if (empty(
$conf->use_javascript_ajax)) {
478 if (!
getDolGlobalString(
'MAIN_USE_JQUERY_MULTISELECT') && !defined(
'REQUIRE_JQUERY_MULTISELECT')) {
485 if (empty($minLengthToAutocomplete)) {
486 $minLengthToAutocomplete = 0;
489 $moreselect2theme = ($morecss ?
dol_escape_js(
' '.$morecss) :
'');
490 $moreselect2theme = preg_replace(
'/widthcentpercentminus[^\s]*/',
'', $moreselect2theme);
492 $tmpplugin =
'select2';
493 $msg =
"\n".
'<!-- JS CODE TO ENABLE '.$tmpplugin.
' for id = '.$htmlname.
' -->
495 $(document).ready(function () {
496 $(\''.(
dol_escape_js(preg_match(
'/^\./', $htmlname) ? $htmlname :
'#'.$htmlname)).
'\').
'.$tmpplugin.'({
498 if (preg_match(
'/onrightofpage/', $morecss)) {
499 $msg .=
' dropdownAutoWidth: true, dropdownParent: $(\'#'.$htmlname.
'\').parent(),
'."\n";
501 $msg .= ' width: \
''.dol_escape_js($widthTypeOfAutocomplete).
'\',
502 minimumInputLength:
'.((int) $minLengthToAutocomplete).',
503 language: (typeof select2arrayoflanguage === \
'undefined\') ? \'en\' : select2arrayoflanguage,
504 matcher: function (params, data) {
505 if ($.trim(params.term) === "") {
508 keywords = (params.term).split(" ");
509 for (var i = 0; i < keywords.length; i++) {
510 if (((data.text).toUpperCase()).indexOf((keywords[i]).toUpperCase()) == -1) {
516 theme: \'default'.dol_escape_js($moreselect2theme).
'\',
517 containerCssClass: \
':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
518 selectionCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
519 dropdownCssClass: \'ui-dialog\',
520 templateResult: function (data, container) { /* Format visible output into combo list */
521 /* Code to add class of origin OPTION propagated to the new select2 <li> tag */
522 if (data.element) { $(container).addClass($(data.element).attr("class")); }
523 //console.log("data html is "+$(data.element).attr("data-html"));
524 if (data.id == '.((int) $idforemptyvalue).
' && $(data.element).attr("data-html") == undefined) {
527 if ($(data.element).attr("data-html") != undefined) {
528 /* If property html set, we decode html entities and use this. */
529 /* Note that HTML content must have been sanitized from js with dol_escape_htmltag(xxx, 0, 0, \'\', 0, 1) when building the select option. */
530 if (typeof htmlEntityDecodeJs === "function") {
531 return htmlEntityDecodeJs($(data.element).attr("data-html"));
536 templateSelection: function (selection) { /* Format visible output of selected value */
537 if (selection.id == '.((int) $idforemptyvalue).
') return \'<span class="placeholder">\'+selection.text+\'</span>\';
538 return selection.text;
540 escapeMarkup: function(markup) {
545 $msg .=
'.select2(\'focus\')';
550 $msg .=
"</script>\n";
651function ajax_constantonoff($code, $input = array(), $entity =
null, $revertonoff = 0, $strict = 0, $forcereload = 0, $marginleftonlyshort = 2, $forcenoajax = 0, $setzeroinsteadofdel = 0, $suffix =
'', $mode =
'', $morecss =
'inline-block', $userconst = 0, $showwarning =
'')
653 global
$conf, $langs, $user, $db;
655 $entity = ((isset($entity) && is_numeric($entity) && $entity >= 0) ? $entity :
$conf->entity);
656 if (!isset($input)) {
660 if (empty(
$conf->use_javascript_ajax) || $forcenoajax) {
662 $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>';
664 $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>';
668 if (is_object($userconst)) {
669 $userconstid = $userconst->id;
670 } elseif (is_numeric($userconst) && $userconst > 0) {
671 $userconstid = $userconst;
672 $userconst =
new User($db);
673 $userconst->fetch($userconstid);
676 $out =
"\n<!-- Ajax code to switch constant ".$code.
" -->".
'
678 $(document).ready(function() {
679 var input = '.json_encode($input).
';
680 var url = \''.DOL_URL_ROOT.
'/core/ajax/constantonoff.php\';
682 var entity = \
''.dol_escape_js($entity).
'\';
683 var strict = \
''.dol_escape_js((
string) $strict).
'\';
684 var userid = \
''.dol_escape_js((
string) $user->id).
'\';
685 var userconst =
'.((int) $userconstid).';
686 var yesButton = \
''.dol_escape_js($langs->transnoentities(
"Yes")).
'\';
687 var noButton = \
''.dol_escape_js($langs->transnoentities(
"No")).
'\';
688 var token = \
''.currentToken().
'\';
689 var warning = \
''.dol_escape_js($showwarning).
'\';
692 $(
"#set_" + code).click(
function() {
697 if (input.alert && input.alert.set) {
698 if (input.alert.set.yesButton) yesButton = input.alert.set.yesButton;
699 if (input.alert.set.noButton) noButton = input.alert.set.noButton;
700 confirmConstantAction(
"set", url, code, input, input.alert.set, entity, yesButton, noButton, strict, userid, token);
702 setConstant(url, code, input, entity, 0,
'.((int) $forcereload).', userid, token, 1, userconst);
707 $(
"#del_" + code).click(
function() {
708 if (input.alert && input.alert.del) {
709 if (input.alert.del.yesButton) yesButton = input.alert.del.yesButton;
710 if (input.alert.del.noButton) noButton = input.alert.del.noButton;
711 confirmConstantAction(
"del", url, code, input, input.alert.del, entity, yesButton, noButton, strict, userid, token);
713 if (empty($setzeroinsteadofdel)) {
714 $out .= ' delConstant(url, code, input, entity, 0,
'.((int) $forcereload).', userid, token, userconst);
';
716 $out .= ' setConstant(url, code, input, entity, 0,
'.((int) $forcereload).', userid, token, 0, userconst);
';
723 if (!empty($userconst) && $userconst instanceof User) {
724 $value = getDolUserString($code, '', $userconst);
726 $value = getDolGlobalString($code);
728 $out .= '<div
id=
"confirm_'.$code.'" title=
"" style=
"display: none;"></div>
';
729 $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>
';
730 $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>
';
754function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input = array(), $morecss = '
', $htmlname = '', $forcenojs = 0, $moreparam = '')
756 global $conf, $langs;
758 if (empty($htmlname)) {
764 if (!empty($conf->use_javascript_ajax) && empty($forcenojs)) {
767 var input =
'.json_encode($input).';
770 $(
"#set_'.$htmlname.'_'.$object->id.'").click(
function() {
771 console.log(
"Click managed by ajax_object_onoff");
772 $.get(
"'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
774 field: \''.dol_escape_js($field).
'\',
777 id: \
''.((int)
$object->id).
'\',
778 token: \
''.currentToken().
'\'
781 $(
"#set_'.$htmlname.'_'.$object->id.'").hide();
782 $(
"#del_'.$htmlname.'_'.$object->id.'").show();
784 if (input.disabled && input.disabled.length > 0) {
785 $.each(input.disabled,
function(key,value) {
786 $(
"#" + value).removeAttr(
"disabled");
787 if ($(
"#" + value).hasClass(
"butActionRefused") == true) {
788 $(
"#" + value).removeClass(
"butActionRefused");
789 $(
"#" + value).addClass(
"butAction");
793 }
else if (input.showhide && input.showhide.length > 0) {
794 $.each(input.showhide,
function(key,value) {
795 $(
"#" + value).show();
802 $(
"#del_'.$htmlname.'_'.$object->id.'").click(
function() {
803 console.log(
"Click managed by ajax_object_onoff");
804 $.get(
"'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
806 field: \''.dol_escape_js($field).
'\',
809 id: \''.((int)
$object->id).
'\',
813 $("#del_'.$htmlname.
'_'.
$object->id.
'").hide();
814 $("#set_'.$htmlname.
'_'.
$object->id.
'").show();
815 // Disable another element
816 if (input.disabled && input.disabled.length > 0) {
817 $.each(input.disabled, function(key,value) {
818 $("#" + value).prop("disabled", true);
819 if ($("#" + value).hasClass("butAction") == true) {
820 $("#" + value).removeClass("butAction");
821 $("#" + value).addClass("butActionRefused");
824 // Hide another element
825 } else if (input.showhide && input.showhide.length > 0) {
826 $.each(input.showhide, function(key,value) {
827 $("#" + value).hide();
836 $switchon =
'switch_on';
837 $switchoff =
'switch_off';
840 $tmparray = explode(
':', $text_on);
841 if (!empty($tmparray[1])) {
842 $text_on = $tmparray[0];
843 $switchon = $tmparray[1];
844 if (!empty($tmparray[2])) {
845 $cssswitchon = $tmparray[2];
848 $tmparray = explode(
':', $text_off);
849 if (!empty($tmparray[1])) {
850 $text_off = $tmparray[0];
851 $switchoff = $tmparray[1];
852 if (!empty($tmparray[2])) {
853 $cssswitchoff = $tmparray[2];
857 if (empty(
$conf->use_javascript_ajax) || $forcenojs) {
858 $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>';
859 $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>';
861 $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>';
862 $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>';
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 ...
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 text field into ...
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)