* Copyright (C) 2007-2015 Regis Houssin * Copyright (C) 2012 Christophe Battarel * Copyright (C) 2024 MDW * Copyright (C) 2024 Frédéric France * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see . * or see https://www.gnu.org/ */ /** * \file htdocs/core/lib/ajax.lib.php * \brief Page called to enhance interface with Javascript and Ajax features. */ /** * Generic function that return javascript to add to transform a common input text or select field into an autocomplete field by calling an Ajax page (ex: /societe/ajax/ajaxcompanies.php). * The HTML field must be an input text with id=search_$htmlname. * This use the jQuery "autocomplete" function. If we want to use the select2, we must instead use input select into functions that call this method. * * @param string $selected Preselected value * @param string $htmlname HTML name of input field * @param string $url Ajax Url to call for request: /path/page.php. Must return a json array ('key'=>id, 'value'=>String shown into input field once selected, 'label'=>String shown into combo list) * @param string $urloption More parameters on URL request * @param int $minLength Minimum number of chars to trigger that Ajax search * @param int $autoselect Automatic selection if just one value (trigger("change") on field is done if search return only 1 result) * @param array $ajaxoptions Multiple options array * - Ex: array('update'=>array('field1','field2'...)) will reset field1 and field2 once select done * - Ex: array('disabled'=> ) * - Ex: array('show'=> ) * - Ex: array('update_textarea'=> ) * - Ex: array('option_disabled'=> id to disable and warning to show if we select a disabled value (this is possible when using autocomplete ajax) * @param string $moreparams More params provided to ajax call * @return string Script */ function ajax_autocompleter($selected, $htmlname, $url, $urloption = '', $minLength = 2, $autoselect = 0, $ajaxoptions = array(), $moreparams = '') { if (empty($minLength)) { $minLength = 1; } $dataforrenderITem = 'ui-autocomplete'; $dataforitem = 'ui-autocomplete-item'; // Allow two constant to use other values for backward compatibility if (defined('JS_QUERY_AUTOCOMPLETE_RENDERITEM')) { $dataforrenderITem = constant('JS_QUERY_AUTOCOMPLETE_RENDERITEM'); } if (defined('JS_QUERY_AUTOCOMPLETE_ITEM')) { $dataforitem = constant('JS_QUERY_AUTOCOMPLETE_ITEM'); } $htmlnamejquery = str_replace('.', '\\\\.', $htmlname); // Input search_htmlname is original field // Input htmlname is a second input field used when using ajax autocomplete. $script = ''; $script .= ''."\n"; $script .= ''; return $script; } /** * Generic function that return javascript to add to a page to transform a common input text field into an autocomplete field by calling an Ajax page (ex: core/ajax/ziptown.php). * The Ajax page can also returns several values (json format) to fill several input fields. * The HTML field must be an input text with id=$htmlname. * This use the jQuery "autocomplete" function. * * @param string $htmlname HTML name of input field * @param string[] $fields Array of key of fields to autocomplete * @param string $url URL for ajax request : /chemin/fichier.php * @param string $option More parameters on URL request * @param int $minLength Minimum number of chars to trigger that Ajax search * @param int $autoselect Automatic selection if just one value * @return string Script */ function ajax_multiautocompleter($htmlname, $fields, $url, $option = '', $minLength = 2, $autoselect = 0) { $script = ''."\n"; $script .= ''; return $script; } /** * Show an ajax dialog * * @param string $title Title of dialog box * @param string $message Message of dialog box * @param int $w Width of dialog box * @param int $h height of dialog box * @return string */ function ajax_dialog($title, $message, $w = 350, $h = 150) { $newtitle = dol_textishtml($title) ? dol_string_nohtmltag($title, 1) : $title; $msg = '
'; $msg .= $message; $msg .= '
'."\n"; $msg .= ''; $msg .= "\n"; return $msg; } /** * Convert a html select field into an ajax combobox. * Use ajax_combobox() only for small combo list! If not, use instead ajax_autocompleter(). * TODO: It is used when COMPANY_USE_SEARCH_TO_SELECT and CONTACT_USE_SEARCH_TO_SELECT are set by html.formcompany.class.php. Should use ajax_autocompleter instead like done by html.form.class.php for select_produits. * * @param string $htmlname Name of html select field ('myid' or '.myclass') * @param array $events More events option. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param int $minLengthToAutocomplete Minimum length of input string to start autocomplete * @param int $forcefocus Force focus on field * @param string $widthTypeOfAutocomplete 'resolve' or 'off' * @param string $idforemptyvalue '-1' * @param string $morecss More css * @return string Return html string to convert a select field into a combo, or '' if feature has been disabled for some reason. * @see selectArrayAjax() of html.form.class */ function ajax_combobox($htmlname, $events = array(), $minLengthToAutocomplete = 0, $forcefocus = 0, $widthTypeOfAutocomplete = 'resolve', $idforemptyvalue = '-1', $morecss = '') { global $conf; // select2 can be disabled for smartphones if (!empty($conf->browser->layout) && $conf->browser->layout == 'phone' && getDolGlobalString('MAIN_DISALLOW_SELECT2_WITH_SMARTPHONE')) { return ''; } if (getDolGlobalString('MAIN_DISABLE_AJAX_COMBOX')) { return ''; } if (empty($conf->use_javascript_ajax)) { return ''; } if (!getDolGlobalString('MAIN_USE_JQUERY_MULTISELECT') && !defined('REQUIRE_JQUERY_MULTISELECT')) { return ''; } if (getDolGlobalString('MAIN_OPTIMIZEFORTEXTBROWSER')) { return ''; } if (empty($minLengthToAutocomplete)) { $minLengthToAutocomplete = 0; } $moreselect2theme = ($morecss ? dol_escape_js(' '.$morecss) : ''); $moreselect2theme = preg_replace('/widthcentpercentminus[^\s]*/', '', $moreselect2theme); $tmpplugin = 'select2'; $msg = "\n".' \n"; $msg .= ajax_event($htmlname, $events); return $msg; } /** * Add event management script. * * @param string $htmlname Name of html select field ('myid' or '.myclass') * @param array $events Add some Ajax events option on change of $htmlname component to call ajax to autofill a HTML element (select#htmlname and #inputautocompletehtmlname) * Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @return string Return JS string to manage event */ function ajax_event($htmlname, $events) { $out = ''; if (is_array($events) && count($events)) { // If an array of js events to do were provided. $out = ' '; } return $out; } /** * On/off button for constant * * @param string $code Name of constant * @param array $input Array of complementary actions to do if success ("disabled"|"enabled'|'set'|'del') => CSS element to switch, 'alert' => message to show, ... Example: array('disabled'=>array(0=>'cssid')) * @param int|null $entity Entity. Current entity is used if null. * @param int $revertonoff 1=Revert on/off * @param int $strict 0=Default, 1=Only the complementary actions "disabled and "enabled" (found into $input) are processed. Use only "disabled" with delConstant and "enabled" with setConstant. * @param int $forcereload Force to reload page if we click/change value (this is supported only when there is no 'alert' option in input) * @param int $marginleftonlyshort 1 = Add a short left margin on picto, 2 = Add a larger left margin on picto, 0 = No left margin. * @param int $forcenoajax 1 = Force to use a ahref link instead of ajax code. * @param int $setzeroinsteadofdel 1 = Set constant to '0' instead of deleting it when $input is empty. * @param string $suffix Suffix to use on the name of the switch picto when option is on. Example: '', '_red' * @param string $mode Add parameter &mode= to the href link (Used for href link) * @param string $morecss More CSS * @return string * @see ajax_object_onoff() to update the status of an object */ function ajax_constantonoff($code, $input = array(), $entity = null, $revertonoff = 0, $strict = 0, $forcereload = 0, $marginleftonlyshort = 2, $forcenoajax = 0, $setzeroinsteadofdel = 0, $suffix = '', $mode = '', $morecss = 'inline-block') { global $conf, $langs, $user; $entity = ((isset($entity) && is_numeric($entity) && $entity >= 0) ? $entity : $conf->entity); if (!isset($input)) { $input = array(); } if (empty($conf->use_javascript_ajax) || $forcenoajax) { if (empty($conf->global->$code)) { $out = ''.img_picto($langs->trans("Disabled"), 'off').''; } else { $out = ''.img_picto($langs->trans("Enabled"), 'on').''; } } else { $out = "\n".' '."\n"; $out .= ''; $out .= ''.($revertonoff ? img_picto($langs->trans("Enabled"), 'switch_on', '', false, 0, 0, '', '', $marginleftonlyshort) : img_picto($langs->trans("Disabled"), 'switch_off', '', false, 0, 0, '', '', $marginleftonlyshort)).''; $out .= ''.($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)).''; $out .= "\n"; } return $out; } /** * On/off button to change a property status of an object * This uses the ajax service objectonoff.php (May be called when MAIN_DIRECT_STATUS_UPDATE is set for some pages) * * @param Object $object Object to set * @param string $code Name of property in object : 'status' or 'status_buy' for product by example * @param string $field Name of database field : 'tosell' or 'tobuy' for product by example * @param string $text_on Text if on ('Text' or 'Text:Picto on:Css picto on') * @param string $text_off Text if off ('Text' or 'Text:Picto off:Css picto off') * @param array $input Array of type->list of CSS element to switch. Example: array('disabled'=>array(0=>'cssid')) * @param string $morecss More CSS * @param string $htmlname Name of HTML component. Keep '' or use a different value if you need to use this component several time on the same page for the same field. * @param int $forcenojs Force the component to work as link post (without javascript) instead of ajax call * @param string $moreparam When $forcenojs=1 then we can add more parameters to the backtopage URL. String must url encoded. Example: 'abc=def&fgh=ijk' * @return string html for button on/off * @see ajax_constantonoff() to update that value of a constant */ function ajax_object_onoff($object, $code, $field, $text_on, $text_off, $input = array(), $morecss = '', $htmlname = '', $forcenojs = 0, $moreparam = '') { global $conf, $langs; if (empty($htmlname)) { $htmlname = $code; } //var_dump($object->module); var_dump($object->element); $out = ''; if (!empty($conf->use_javascript_ajax) && empty($forcenojs)) { $out .= ''; } $switchon = 'switch_on'; $switchoff = 'switch_off'; $cssswitchon = ''; $cssswitchoff = ''; $tmparray = explode(':', $text_on); if (!empty($tmparray[1])) { $text_on = $tmparray[0]; $switchon = $tmparray[1]; if (!empty($tmparray[2])) { $cssswitchon = $tmparray[2]; } } $tmparray = explode(':', $text_off); if (!empty($tmparray[1])) { $text_off = $tmparray[0]; $switchoff = $tmparray[1]; if (!empty($tmparray[2])) { $cssswitchoff = $tmparray[2]; } } if (empty($conf->use_javascript_ajax) || $forcenojs) { $out .= ''.img_picto($langs->trans($text_off), $switchoff, '', false, 0, 0, '', $cssswitchoff).''; $out .= ''.img_picto($langs->trans($text_on), $switchon, '', false, 0, 0, '', $cssswitchon).''; } else { $out .= ''.img_picto($langs->trans($text_off), $switchoff, '', false, 0, 0, '', $cssswitchoff).''; $out .= ''.img_picto($langs->trans($text_on), $switchon, '', false, 0, 0, '', $cssswitchon).''; } return $out; }