47function ajax_autocompleter($selected, $htmlname, $url, $urloption =
'', $minLength = 2, $autoselect = 0, $ajaxoptions = array(), $moreparams =
'')
49 if (empty($minLength)) {
53 $dataforrenderITem =
'ui-autocomplete';
54 $dataforitem =
'ui-autocomplete-item';
56 if (defined(
'JS_QUERY_AUTOCOMPLETE_RENDERITEM')) {
57 $dataforrenderITem = constant(
'JS_QUERY_AUTOCOMPLETE_RENDERITEM');
59 if (defined(
'JS_QUERY_AUTOCOMPLETE_ITEM')) {
60 $dataforitem = constant(
'JS_QUERY_AUTOCOMPLETE_ITEM');
63 $htmlnamejquery = str_replace(
'.',
'\\\\.', $htmlname);
67 $script =
'<input type="hidden" name="'.$htmlname.
'" id="'.$htmlname.
'" value="'.$selected.
'" '.($moreparams ? $moreparams :
'').
' />';
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 */
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 */
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("");
85 // Check options for secondary actions when keyup
86 $("input#search_'.$htmlnamejquery.
'").keyup(function() {
87 if ($(this).val().length == 0)
89 $("#search_'.$htmlnamejquery.
'").val("");
90 $("#'.$htmlnamejquery.
'").val("").trigger("change");
91 if (options.option_disabled) {
92 $("#" + options.option_disabled).removeAttr("disabled");
94 if (options.disabled) {
95 $.each(options.disabled, function(key, value) {
96 $("#" + value).removeAttr("disabled");
100 $.each(options.update, function(key, value) {
101 $("#" + key).val("").trigger("change");
105 $.each(options.show, function(key, value) {
106 $("#" + value).hide().trigger("hide");
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("");
114 $("#" + key).html("");
121 $("input#search_'.$htmlnamejquery.
'").autocomplete({
122 source: function( request, response ) {
123 $.get("'.$url.($urloption ?
'?'.$urloption :
'').
'", { "'.str_replace(
'.',
'_', $htmlname).
'": request.term }, function(data){
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");
132 if (item.label != null) {
133 label = item.label.toString();
136 if (options.update) {
137 $.each(options.update, function(key, value) {
138 update[key] = item[value];
142 if (options.update_textarea) {
143 $.each(options.update_textarea, function(key, value) {
144 textarea[key] = item[value];
148 console.log("Return value from GET to the rest of code");
149 return { label: label,
152 disabled: item.disabled,
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 description : item.description,
165 ref_customer: item.ref_customer,
167 default_vat_code: item.default_vat_code
171 console.error("Error: Ajax url '.$url.($urloption ?
'?'.$urloption :
'').
' has returned an empty page. Should be an empty json array.");
176 minLength: '.((
int) $minLength).
',
177 select: function( event, ui ) { // Function ran once new value has been selected into javascript combo
178 console.log("We will trigger change on input '.$htmlname.
' because of the select definition of autocomplete code for input#search_'.$htmlname.
'");
179 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");
181 console.log("Propagate before some properties retrieved by ajax into data-xxx properties of #'.$htmlnamejquery.
' component");
182 //console.log(ui.item);
184 // For supplier price and customer when price by quantity is off
185 $("#'.$htmlnamejquery.
'").attr("data-up", ui.item.price_ht);
186 $("#'.$htmlnamejquery.
'").attr("data-up-locale", ui.item.price_unit_ht_locale);
187 $("#'.$htmlnamejquery.
'").attr("data-base", ui.item.pricebasetype);
188 $("#'.$htmlnamejquery.
'").attr("data-qty", ui.item.qty);
189 $("#'.$htmlnamejquery.
'").attr("data-discount", ui.item.discount);
190 $("#'.$htmlnamejquery.
'").attr("data-description", ui.item.description);
191 $("#'.$htmlnamejquery.
'").attr("data-ref-customer", ui.item.ref_customer);
192 $("#'.$htmlnamejquery.
'").attr("data-tvatx", ui.item.tva_tx);
193 $("#'.$htmlnamejquery.
'").attr("data-default-vat-code", ui.item.default_vat_code);
197 // For customer price when PRODUIT_CUSTOMER_PRICES_BY_QTY is on
198 console.log("PRODUIT_CUSTOMER_PRICES_BY_QTY is on, propagate also prices by quantity into data-pbqxxx properties");
199 $("#'.$htmlnamejquery.
'").attr("data-pbq", ui.item.pbq);
200 $("#'.$htmlnamejquery.
'").attr("data-pbqup", ui.item.price_ht);
201 $("#'.$htmlnamejquery.
'").attr("data-pbqbase", ui.item.pricebasetype);
202 $("#'.$htmlnamejquery.
'").attr("data-pbqqty", ui.item.qty);
203 $("#'.$htmlnamejquery.
'").attr("data-pbqpercent", ui.item.discount);
207 // A new value has been selected, we trigger the handlers on #htmlnamejquery
208 console.log("Trigger changes on #'.$htmlnamejquery.
'");
209 $("#'.$htmlnamejquery.
'").val(ui.item.id).trigger("change"); // Select new value
211 // Complementary actions
213 // Disable an element
214 if (options.option_disabled) {
215 console.log("Make action option_disabled on #"+options.option_disabled+" with disabled="+ui.item.disabled)
216 if (ui.item.disabled) {
217 $("#" + options.option_disabled).prop("disabled", true);
219 $.jnotify(options.error, "error", true); // Output with jnotify the error message
221 if (options.warning) {
222 $.jnotify(options.warning, "warning", false); // Output with jnotify the warning message
225 $("#" + options.option_disabled).removeAttr("disabled");
229 if (options.disabled) {
230 console.log("Make action disabled on each "+options.option_disabled)
231 $.each(options.disabled, function(key, value) {
232 $("#" + value).prop("disabled", true);
236 console.log("Make action show on each "+options.show)
237 $.each(options.show, function(key, value) {
238 $("#" + value).show().trigger("show");
243 if (ui.item.update) {
244 console.log("Make action update on each ui.item.update (if there is)")
245 // loop on each "update" fields
246 $.each(ui.item.update, function(key, value) {
247 console.log("Set value "+value+" into #"+key);
248 $("#" + key).val(value).trigger("change");
251 if (ui.item.textarea) {
252 console.log("Make action textarea on each ui.item.textarea (if there is)")
253 $.each(ui.item.textarea, function(key, value) {
254 if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances[key] != "undefined") {
255 CKEDITOR.instances[key].setData(value);
256 CKEDITOR.instances[key].focus();
258 $("#" + key).html(value);
259 $("#" + key).focus();
263 console.log("ajax_autocompleter new value selected, we trigger change also on original component so on field #search_'.$htmlname.
'");
265 $("#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.
268 }).data("'.$dataforrenderITem.
'")._renderItem = function( ul, item ) {
270 .data( "'.$dataforitem.
'", item ) // jQuery UI > 1.10.0
271 .append( \'<a><span class="tag">\' + item.label + "</span></a>" )
276 $script .=
'</script>';
447function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = 0, $forcefocus = 0, $widthTypeOfAutocomplete =
'resolve', $idforemptyvalue =
'-1', $morecss =
'')
452 if (!empty($conf->browser->layout) && $conf->browser->layout ==
'phone' &&
getDolGlobalString(
'MAIN_DISALLOW_SELECT2_WITH_SMARTPHONE')) {
459 if (empty($conf->use_javascript_ajax)) {
462 if (!
getDolGlobalString(
'MAIN_USE_JQUERY_MULTISELECT') && !defined(
'REQUIRE_JQUERY_MULTISELECT')) {
469 if (empty($minLengthToAutocomplete)) {
470 $minLengthToAutocomplete = 0;
473 $moreselect2theme = ($morecss ?
dol_escape_js(
' '.$morecss) :
'');
474 $moreselect2theme = preg_replace(
'/widthcentpercentminus[^\s]*/',
'', $moreselect2theme);
476 $tmpplugin =
'select2';
477 $msg =
"\n".
'<!-- JS CODE TO ENABLE '.$tmpplugin.
' for id = '.$htmlname.
' -->
479 $(document).ready(function () {
480 $(\''.(preg_match(
'/^\./', $htmlname) ? $htmlname :
'#'.$htmlname).
'\').
'.$tmpplugin.'({
482 if (preg_match(
'/onrightofpage/', $morecss)) {
483 $msg .=
' dropdownAutoWidth: true, dropdownParent: $(\'#'.$htmlname.
'\').parent(),
'."\n";
485 $msg .= ' width: \
''.dol_escape_js($widthTypeOfAutocomplete).
'\',
486 minimumInputLength:
'.((int) $minLengthToAutocomplete).',
487 language: select2arrayoflanguage,
488 matcher:
function (params, data) {
489 if ($.trim(params.term) ===
"") {
492 keywords = (params.term).split(
" ");
493 for (var i = 0; i < keywords.length; i++) {
494 if (((data.text).toUpperCase()).indexOf((keywords[i]).toUpperCase()) == -1) {
500 theme: \
'default'.$moreselect2theme.
'\',
501 containerCssClass: \
':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
502 selectionCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
503 dropdownCssClass: \'ui-dialog\',
504 templateResult: function (data, container) { /* Format visible output into combo list */
505 /* Code to add class of origin OPTION propagated to the new select2 <li> tag */
506 if (data.element) { $(container).addClass($(data.element).attr("class")); }
507 //console.log("data html is "+$(data.element).attr("data-html"));
508 if (data.id == '.((int) $idforemptyvalue).
' && $(data.element).attr("data-html") == undefined) {
511 if ($(data.element).attr("data-html") != undefined) {
512 /* If property html set, we decode html entities and use this. */
513 /* Note that HTML content must have been sanitized from js with dol_escape_htmltag(xxx, 0, 0, \'\', 0, 1) when building the select option. */
514 return htmlEntityDecodeJs($(data.element).attr("data-html"));
518 templateSelection: function (selection) { /* Format visible output of selected value */
519 if (selection.id == '.((int) $idforemptyvalue).
') return \'<span class="placeholder">\'+selection.text+\'</span>\';
520 return selection.text;
522 escapeMarkup: function(markup) {
527 $msg .=
'.select2(\'focus\')';
532 $msg .=
"</script>\n";
628function ajax_constantonoff($code, $input = array(), $entity =
null, $revertonoff = 0, $strict = 0, $forcereload = 0, $marginleftonlyshort = 2, $forcenoajax = 0, $setzeroinsteadofdel = 0, $suffix =
'', $mode =
'', $morecss =
'inline-block')
630 global $conf, $langs, $user;
632 $entity = ((isset($entity) && is_numeric($entity) && $entity >= 0) ? $entity : $conf->entity);
633 if (!isset($input)) {
637 if (empty($conf->use_javascript_ajax) || $forcenoajax) {
638 if (empty($conf->global->$code)) {
639 $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>';
641 $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>';
644 $out =
"\n<!-- Ajax code to switch constant ".$code.
" -->".
'
646 $(document).ready(function() {
647 var input = '.json_encode($input).
';
648 var url = \''.DOL_URL_ROOT.
'/core/ajax/constantonoff.php\';
650 var entity = \
''.dol_escape_js($entity).
'\';
651 var strict = \
''.dol_escape_js($strict).
'\';
652 var userid = \
''.dol_escape_js($user->id).
'\';
653 var yesButton = \
''.dol_escape_js($langs->transnoentities(
"Yes")).
'\';
654 var noButton = \
''.dol_escape_js($langs->transnoentities(
"No")).
'\';
655 var token = \
''.currentToken().
'\';
658 $(
"#set_" + code).click(
function() {
659 if (input.alert && input.alert.set) {
660 if (input.alert.set.yesButton) yesButton = input.alert.set.yesButton;
661 if (input.alert.set.noButton) noButton = input.alert.set.noButton;
662 confirmConstantAction(
"set", url, code, input, input.alert.set, entity, yesButton, noButton, strict, userid, token);
664 setConstant(url, code, input, entity, 0,
'.((int) $forcereload).', userid, token);
669 $(
"#del_" + code).click(
function() {
670 if (input.alert && input.alert.del) {
671 if (input.alert.del.yesButton) yesButton = input.alert.del.yesButton;
672 if (input.alert.del.noButton) noButton = input.alert.del.noButton;
673 confirmConstantAction(
"del", url, code, input, input.alert.del, entity, yesButton, noButton, strict, userid, token);
675 if (empty($setzeroinsteadofdel)) {
676 $out .=' delConstant(url, code, input, entity, 0,
'.((int) $forcereload).', userid, token);
';
678 $out .=' setConstant(url, code, input, entity, 0,
'.((int) $forcereload).', userid, token, 0);
';
685 $out .= '<div
id=
"confirm_'.$code.'" title=
"" style=
"display: none;"></div>
';
686 $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>
';
687 $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>
';
709function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input = array(), $morecss = '
', $htmlname = '', $forcenojs = 0)
711 global $conf, $langs;
713 if (empty($htmlname)) {
716 //var_dump($object->module); var_dump($object->element);
720 if (!empty($conf->use_javascript_ajax)) {
723 var input =
'.json_encode($input).';
726 $(
"#set_'.$htmlname.'_'.$object->id.'").click(
function() {
727 console.log(
"Click managed by ajax_object_onoff");
728 $.get(
"'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
730 field: \''.dol_escape_js($field).
'\',
732 element: \''.dol_escape_js((empty($object->module) || $object->module == $object->element) ? $object->element : $object->element.
'@'.$object->module).
'\',
733 id: \
''.((int) $object->id).
'\',
734 token: \
''.currentToken().
'\'
737 $(
"#set_'.$htmlname.'_'.$object->id.'").hide();
738 $(
"#del_'.$htmlname.'_'.$object->id.'").show();
740 if (input.disabled && input.disabled.length > 0) {
741 $.each(input.disabled,
function(key,value) {
742 $(
"#" + value).removeAttr(
"disabled");
743 if ($(
"#" + value).hasClass(
"butActionRefused") == true) {
744 $(
"#" + value).removeClass(
"butActionRefused");
745 $(
"#" + value).addClass(
"butAction");
749 }
else if (input.showhide && input.showhide.length > 0) {
750 $.each(input.showhide,
function(key,value) {
751 $(
"#" + value).show();
758 $(
"#del_'.$htmlname.'_'.$object->id.'").click(
function() {
759 console.log(
"Click managed by ajax_object_onoff");
760 $.get(
"'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
762 field: \''.dol_escape_js($field).
'\',
764 element: \''.
dol_escape_js((empty($object->module) || $object->module == $object->element) ? $object->element : $object->element.
'@'.$object->module).
'\',
765 id: \''.((int) $object->id).
'\',
769 $("#del_'.$htmlname.
'_'.$object->id.
'").hide();
770 $("#set_'.$htmlname.
'_'.$object->id.
'").show();
771 // Disable another element
772 if (input.disabled && input.disabled.length > 0) {
773 $.each(input.disabled, function(key,value) {
774 $("#" + value).prop("disabled", true);
775 if ($("#" + value).hasClass("butAction") == true) {
776 $("#" + value).removeClass("butAction");
777 $("#" + value).addClass("butActionRefused");
780 // Hide another element
781 } else if (input.showhide && input.showhide.length > 0) {
782 $.each(input.showhide, function(key,value) {
783 $("#" + value).hide();
792 $switchon =
'switch_on';
793 $switchoff =
'switch_off';
796 $tmparray = explode(
':', $text_on);
797 if (!empty($tmparray[1])) {
798 $text_on = $tmparray[0];
799 $switchon = $tmparray[1];
800 if (!empty($tmparray[2])) {
801 $cssswitchon = $tmparray[2];
804 $tmparray = explode(
':', $text_off);
805 if (!empty($tmparray[1])) {
806 $text_off = $tmparray[0];
807 $switchoff = $tmparray[1];
808 if (!empty($tmparray[2])) {
809 $cssswitchoff = $tmparray[2];
813 if (empty($conf->use_javascript_ajax) || $forcenojs) {
814 $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>';
815 $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>';
817 $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>';
818 $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)