47 function 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");
133 var label = item.label.toString();
135 if (options.update) {
136 $.each(options.update, function(key, value) {
137 update[key] = item[value];
141 if (options.update_textarea) {
142 $.each(options.update_textarea, function(key, value) {
143 textarea[key] = item[value];
146 console.log("Return value from GET to the rest of code");
147 return { label: label, value: item.value, id: item.key, disabled: item.disabled,
153 discount: item.discount,
154 pricebasetype: item.pricebasetype,
155 price_ht: item.price_ht,
156 price_ttc: item.price_ttc,
157 description : item.description,
158 ref_customer: item.ref_customer,
159 tva_tx: item.tva_tx }
162 console.error("Error: Ajax url '.$url.($urloption ?
'?'.$urloption :
'').
' has returned an empty page. Should be an empty json array.");
167 minLength: '.((
int) $minLength).
',
168 select: function( event, ui ) { // Function ran once new value has been selected into javascript combo
169 console.log("We will trigger change on input '.$htmlname.
' because of the select definition of autocomplete code for input#search_'.$htmlname.
'");
170 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");
172 console.log("Propagate before some properties retrieved by ajax into data-xxx properties");
174 // For supplier price and customer when price by quantity is off
175 $("#'.$htmlnamejquery.
'").attr("data-up", ui.item.price_ht);
176 $("#'.$htmlnamejquery.
'").attr("data-base", ui.item.pricebasetype);
177 $("#'.$htmlnamejquery.
'").attr("data-qty", ui.item.qty);
178 $("#'.$htmlnamejquery.
'").attr("data-discount", ui.item.discount);
179 $("#'.$htmlnamejquery.
'").attr("data-description", ui.item.description);
180 $("#'.$htmlnamejquery.
'").attr("data-ref-customer", ui.item.ref_customer);
181 $("#'.$htmlnamejquery.
'").attr("data-tvatx", ui.item.tva_tx);
183 if (!empty($conf->global->PRODUIT_CUSTOMER_PRICES_BY_QTY)) {
185 // For customer price when PRODUIT_CUSTOMER_PRICES_BY_QTY is on
186 $("#'.$htmlnamejquery.
'").attr("data-pbq", ui.item.pbq);
187 $("#'.$htmlnamejquery.
'").attr("data-pbqup", ui.item.price_ht);
188 $("#'.$htmlnamejquery.
'").attr("data-pbqbase", ui.item.pricebasetype);
189 $("#'.$htmlnamejquery.
'").attr("data-pbqqty", ui.item.qty);
190 $("#'.$htmlnamejquery.
'").attr("data-pbqpercent", ui.item.discount);
194 $("#'.$htmlnamejquery.
'").val(ui.item.id).trigger("change"); // Select new value
196 // Disable an element
197 if (options.option_disabled) {
198 console.log("Make action option_disabled on #"+options.option_disabled+" with disabled="+ui.item.disabled)
199 if (ui.item.disabled) {
200 $("#" + options.option_disabled).prop("disabled", true);
202 $.jnotify(options.error, "error", true); // Output with jnotify the error message
204 if (options.warning) {
205 $.jnotify(options.warning, "warning", false); // Output with jnotify the warning message
208 $("#" + options.option_disabled).removeAttr("disabled");
212 if (options.disabled) {
213 console.log("Make action disabled on each "+options.option_disabled)
214 $.each(options.disabled, function(key, value) {
215 $("#" + value).prop("disabled", true);
219 console.log("Make action show on each "+options.show)
220 $.each(options.show, function(key, value) {
221 $("#" + value).show().trigger("show");
226 if (ui.item.update) {
227 console.log("Make action update on each ui.item.update")
228 // loop on each "update" fields
229 $.each(ui.item.update, function(key, value) {
230 console.log("Set value "+value+" into #"+key);
231 $("#" + key).val(value).trigger("change");
234 if (ui.item.textarea) {
235 console.log("Make action textarea on each ui.item.textarea")
236 $.each(ui.item.textarea, function(key, value) {
237 if (typeof CKEDITOR == "object" && typeof CKEDITOR.instances != "undefined" && CKEDITOR.instances[key] != "undefined") {
238 CKEDITOR.instances[key].setData(value);
239 CKEDITOR.instances[key].focus();
241 $("#" + key).html(value);
242 $("#" + key).focus();
246 console.log("ajax_autocompleter new value selected, we trigger change also on original component so on field #search_'.$htmlname.
'");
248 $("#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.
251 }).data("'.$dataforrenderITem.
'")._renderItem = function( ul, item ) {
253 .data( "'.$dataforitem.
'", item ) // jQuery UI > 1.10.0
254 .append( \'<a><span class="tag">\' + item.label + "</span></a>" )
259 $script .=
'</script>';
280 $script =
'<!-- Autocomplete -->'.
"\n";
281 $script .=
'<script>';
282 $script .=
'jQuery(document).ready(function() {
283 var fields = '.json_encode($fields).
';
284 var nboffields = fields.length;
285 var autoselect = '.$autoselect.
';
286 //alert(fields + " " + nboffields);
288 jQuery("input#'.$htmlname.
'").autocomplete({
290 minLength: '.$minLength.
',
291 source: function( request, response ) {
292 jQuery.getJSON( "'.$url.($option ?
'?'.$option :
'').
'", { '.$htmlname.
': request.term }, function(data){
293 response( jQuery.map( data, function( item ) {
294 if (autoselect == 1 && data.length == 1) {
295 jQuery("#'.$htmlname.
'").val(item.value);
296 // TODO move this to specific request
298 jQuery("#state_id").html(item.states);
300 for (i=0;i<nboffields;i++) {
301 if (item[fields[i]]) { // If defined
302 //alert(item[fields[i]]);
303 jQuery("#" + fields[i]).val(item[fields[i]]);
311 select: function( event, ui ) {
313 for (i=0;i<nboffields;i++) {
314 //alert(fields[i] + " = " + ui.item[fields[i]]);
315 if (fields[i]=="selectcountry_id")
317 if (ui.item[fields[i]] > 0) // Do not erase country if unknown
319 oldvalue=jQuery("#" + fields[i]).val();
320 newvalue=ui.item[fields[i]];
321 //alert(oldvalue+" "+newvalue);
322 jQuery("#" + fields[i]).val(ui.item[fields[i]]);
323 if (oldvalue != newvalue) // To force select2 to refresh visible content
325 needtotrigger="#" + fields[i];
328 // If we set new country and new state, we need to set a new list of state to allow change
329 if (ui.item.states && ui.item["state_id"] != jQuery("#state_id").value) {
330 jQuery("#state_id").html(ui.item.states);
334 else if (fields[i]=="state_id" || fields[i]=="state_id")
336 if (ui.item[fields[i]] > 0) // Do not erase state if unknown
338 oldvalue=jQuery("#" + fields[i]).val();
339 newvalue=ui.item[fields[i]];
340 //alert(oldvalue+" "+newvalue);
341 jQuery("#" + fields[i]).val(ui.item[fields[i]]); // This may fails if not correct country
342 if (oldvalue != newvalue) // To force select2 to refresh visible content
344 needtotrigger="#" + fields[i];
348 else if (ui.item[fields[i]]) { // If defined
349 oldvalue=jQuery("#" + fields[i]).val();
350 newvalue=ui.item[fields[i]];
351 //alert(oldvalue+" "+newvalue);
352 jQuery("#" + fields[i]).val(ui.item[fields[i]]);
353 if (oldvalue != newvalue) // To force select2 to refresh visible content
355 needtotrigger="#" + fields[i];
359 if (needtotrigger != "") // To force select2 to refresh visible content
361 // 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
362 // This is required for example when changing zip with autocomplete that change the country
363 jQuery(needtotrigger).delay(500).queue(function() {
364 jQuery(this).trigger("change");
371 $script .=
'</script>';
390 $msg =
'<div id="dialog-info" title="'.dol_escape_htmltag($newtitle).
'">';
392 $msg .=
'</div>'.
"\n";
395 jQuery("#dialog-info").dialog({
402 jQuery(this).dialog(\'close\');
429 function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = 0, $forcefocus = 0, $widthTypeOfAutocomplete =
'resolve', $idforemptyvalue =
'-1')
434 if (!empty($conf->browser->layout) && $conf->browser->layout ==
'phone' && !empty($conf->global->MAIN_DISALLOW_SELECT2_WITH_SMARTPHONE)) {
438 if (!empty($conf->global->MAIN_DISABLE_AJAX_COMBOX)) {
441 if (empty($conf->use_javascript_ajax)) {
444 if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && !defined(
'REQUIRE_JQUERY_MULTISELECT')) {
447 if (!empty($conf->global->MAIN_OPTIMIZEFORTEXTBROWSER)) {
451 if (empty($minLengthToAutocomplete)) {
452 $minLengthToAutocomplete = 0;
455 $tmpplugin =
'select2';
456 $msg =
"\n".
'<!-- JS CODE TO ENABLE '.$tmpplugin.
' for id = '.$htmlname.
' -->
458 $(document).ready(function () {
459 $(\''.(preg_match(
'/^\./', $htmlname) ? $htmlname :
'#'.$htmlname).
'\').
'.$tmpplugin.'({
461 width: \''.$widthTypeOfAutocomplete.
'\',
462 minimumInputLength:
'.$minLengthToAutocomplete.',
463 language: select2arrayoflanguage,
464 containerCssClass: \
':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
465 selectionCssClass: \':all:\', /* Line to add class of origin SELECT propagated to the new <span class="select2-selection...> tag */
466 templateResult: function (data, container) { /* Format visible output into combo list */
467 /* Code to add class of origin OPTION propagated to the new select2 <li> tag */
468 if (data.element) { $(container).addClass($(data.element).attr("class")); }
469 //console.log($(data.element).attr("data-html"));
470 if (data.id == '.((int) $idforemptyvalue).
' && $(data.element).attr("data-html") == undefined) {
473 if ($(data.element).attr("data-html") != undefined) return htmlEntityDecodeJs($(data.element).attr("data-html")); // If property html set, we decode html entities and use this
476 templateSelection: function (selection) { /* Format visible output of selected value */
477 if (selection.id == '.((int) $idforemptyvalue).
') return \'<span class="placeholder">\'+selection.text+\'</span>\';
478 return selection.text;
480 escapeMarkup: function(markup) {
483 dropdownCssClass: \'ui-dialog\'
486 $msg .=
'.select2(\'focus\')';
490 if (is_array($events) && count($events)) {
492 jQuery("#'.$htmlname.
'").change(function () {
493 var obj = '.json_encode($events).
';
494 $.each(obj, function(key,values) {
495 if (values.method.length) {
496 runJsCodeForEvent'.$htmlname.
'(values);
501 function runJsCodeForEvent'.$htmlname.
'(obj) {
502 var id = $("#'.$htmlname.
'").val();
503 var method = obj.method;
505 var htmlname = obj.htmlname;
506 var showempty = obj.showempty;
507 console.log("Run runJsCodeForEvent-'.$htmlname.
' from ajax_combobox id="+id+" method="+method+" showempty="+showempty+" url="+url+" htmlname="+htmlname);
516 $.each(obj.params, function(key,action) {
518 var num = response.num;
520 $("#" + key).removeAttr(action);
522 $("#" + key).attr(action, action);
526 $("select#" + htmlname).html(response.value);
528 var selecthtml_str = response.value;
529 var selecthtml_dom=$.parseHTML(selecthtml_str);
530 if (typeof(selecthtml_dom[0][0]) !== \'undefined\') {
531 $("#inputautocomplete"+htmlname).val(selecthtml_dom[0][0].innerHTML);
534 $("#inputautocomplete"+htmlname).val("");
536 $("select#" + htmlname).change(); /* Trigger event change */
543 $msg .=
"</script>\n";
564 function ajax_constantonoff($code, $input = array(), $entity = null, $revertonoff = 0, $strict = 0, $forcereload = 0, $marginleftonlyshort = 2, $forcenoajax = 0, $setzeroinsteadofdel = 0, $suffix =
'', $mode =
'')
566 global $conf, $langs, $user;
568 $entity = ((isset($entity) && is_numeric($entity) && $entity >= 0) ? $entity : $conf->entity);
569 if (!isset($input)) {
573 if (empty($conf->use_javascript_ajax) || $forcenoajax) {
574 if (empty($conf->global->$code)) {
575 print
'<a 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>';
577 print
'<a 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>';
580 $out =
"\n<!-- Ajax code to switch constant ".$code.
" -->".
'
582 $(document).ready(function() {
583 var input = '.json_encode($input).
';
584 var url = \''.DOL_URL_ROOT.
'/core/ajax/constantonoff.php\';
586 var entity = \
''.dol_escape_js($entity).
'\';
587 var strict = \
''.dol_escape_js($strict).
'\';
588 var userid = \
''.dol_escape_js($user->id).
'\';
589 var yesButton = \
''.dol_escape_js($langs->transnoentities(
"Yes")).
'\';
590 var noButton = \
''.dol_escape_js($langs->transnoentities(
"No")).
'\';
591 var token = \
''.currentToken().
'\';
594 $(
"#set_" +
code).click(
function() {
595 if (input.alert && input.alert.set) {
596 if (input.alert.set.yesButton) yesButton = input.alert.set.yesButton;
597 if (input.alert.set.noButton) noButton = input.alert.set.noButton;
598 confirmConstantAction(
"set", url,
code, input, input.alert.set, entity, yesButton, noButton, strict, userid, token);
600 setConstant(url,
code, input, entity, 0,
'.((int) $forcereload).', userid, token);
605 $(
"#del_" +
code).click(
function() {
606 if (input.alert && input.alert.del) {
607 if (input.alert.del.yesButton) yesButton = input.alert.del.yesButton;
608 if (input.alert.del.noButton) noButton = input.alert.del.noButton;
609 confirmConstantAction(
"del", url,
code, input, input.alert.del, entity, yesButton, noButton, strict, userid, token);
611 if (empty($setzeroinsteadofdel)) {
612 $out .=' delConstant(url,
code, input, entity, 0,
'.((int) $forcereload).', userid, token);
';
614 $out .=' setConstant(url,
code, input, entity, 0,
'.((int) $forcereload).', userid, token, 0);
';
621 $out .= '<div
id=
"confirm_'.$code.'" title=
"" style=
"display: none;"></div>
';
622 $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>
';
623 $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>
';
643 function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input = array(), $morecss = '')
649 var input =
'.json_encode($input).';
652 $(
"#set_'.$code.'_'.$object->id.'").click(
function() {
653 $.get(
"'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
655 field: \''.$field.
'\',
657 element: \''.$object->element.
'\',
658 id: \
''.$object->id.
'\',
659 token: \
''.newToken().
'\'
662 $(
"#set_'.$code.'_'.$object->id.'").hide();
663 $(
"#del_'.$code.'_'.$object->id.'").show();
665 if (input.disabled && input.disabled.length > 0) {
666 $.each(input.disabled,
function(key,value) {
667 $(
"#" + value).removeAttr(
"disabled");
668 if ($(
"#" + value).hasClass(
"butActionRefused") ==
true) {
669 $(
"#" + value).removeClass(
"butActionRefused");
670 $(
"#" + value).addClass(
"butAction");
674 }
else if (input.showhide && input.showhide.length > 0) {
675 $.each(input.showhide,
function(key,value) {
676 $(
"#" + value).show();
683 $(
"#del_'.$code.'_'.$object->id.'").click(
function() {
684 $.get(
"'.DOL_URL_ROOT.'/core/ajax/objectonoff.php", {
686 field: \''.$field.
'\',
688 element: \''.$object->element.
'\',
689 id: \
''.$object->id.
'\',
690 token: \
''.newToken().
'\'
693 $(
"#del_'.$code.'_'.$object->id.'").hide();
694 $(
"#set_'.$code.'_'.$object->id.'").show();
696 if (input.disabled && input.disabled.length > 0) {
697 $.each(input.disabled,
function(key,value) {
698 $(
"#" + value).prop(
"disabled",
true);
699 if ($(
"#" + value).hasClass(
"butAction") ==
true) {
700 $(
"#" + value).removeClass(
"butAction");
701 $(
"#" + value).addClass(
"butActionRefused");
705 }
else if (input.showhide && input.showhide.length > 0) {
706 $.each(input.showhide,
function(key,value) {
707 $(
"#" + value).hide();
714 $out .= '<span
id=
"set_'.$code.'_'.$object->id.'" class=
"linkobject '.($object->$code == 1 ? 'hideobject' : '').($morecss ? ' '.$morecss : '').'">
'.img_picto($langs->trans($text_off), 'switch_off
').'</span>
';
715 $out .= '<span
id=
"del_'.$code.'_'.$object->id.'" class=
"linkobject '.($object->$code == 1 ? '' : 'hideobject').($morecss ? ' '.$morecss : '').'">
'.img_picto($langs->trans($text_on), 'switch_on
').'</span>
';
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto= 'UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
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...
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
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...
print *****$script_file(".$version.") pid code
! Closing after partial payment: discount_vat, badcustomer or badsupplier, bankcharge, other ! Closing when no payment: replaced, abandoned
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
ajax_dialog($title, $message, $w=350, $h=150)
Show an ajax dialog.
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete= 'resolve', $idforemptyvalue= '-1')
Convert a html select field into an ajax combobox.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
ajax_constantonoff($code, $input=array(), $entity=null, $revertonoff=0, $strict=0, $forcereload=0, $marginleftonlyshort=2, $forcenoajax=0, $setzeroinsteadofdel=0, $suffix= '', $mode= '')
On/off button for constant.
dol_textishtml($msg, $option=0)
Return if a text is a html content.