lib_foot.js.php 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. <?php
  2. /* Copyright (C) 2017 Laurent Destailleur <eldy@users.sourceforge.net>
  3. *
  4. * This program is free software; you can redistribute it and/or modify
  5. * it under the terms of the GNU General Public License as published by
  6. * the Free Software Foundation; either version 3 of the License, or
  7. * (at your option) any later version.
  8. *
  9. * This program is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  12. * GNU General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU General Public License
  15. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  16. * or see https://www.gnu.org/
  17. */
  18. /**
  19. * \file htdocs/core/js/lib_foot.js.php
  20. * \brief File that include javascript functions (included if option use_javascript activated)
  21. */
  22. if (!defined('NOREQUIRESOC')) {
  23. define('NOREQUIRESOC', '1');
  24. }
  25. if (!defined('NOCSRFCHECK')) {
  26. define('NOCSRFCHECK', 1);
  27. }
  28. if (!defined('NOTOKENRENEWAL')) {
  29. define('NOTOKENRENEWAL', 1);
  30. }
  31. if (!defined('NOLOGIN')) {
  32. define('NOLOGIN', 1);
  33. }
  34. if (!defined('NOREQUIREMENU')) {
  35. define('NOREQUIREMENU', 1);
  36. }
  37. if (!defined('NOREQUIREHTML')) {
  38. define('NOREQUIREHTML', 1);
  39. }
  40. if (!defined('NOREQUIREAJAX')) {
  41. define('NOREQUIREAJAX', '1');
  42. }
  43. session_cache_limiter('public');
  44. require_once '../../main.inc.php';
  45. /*
  46. * View
  47. */
  48. // Define javascript type
  49. top_httphead('text/javascript; charset=UTF-8');
  50. // Important: Following code is to avoid page request by browser and PHP CPU at each Dolibarr page access.
  51. if (empty($dolibarr_nocache)) {
  52. header('Cache-Control: max-age=10800, public, must-revalidate');
  53. } else {
  54. header('Cache-Control: no-cache');
  55. }
  56. //var_dump($conf);
  57. // Wrapper to show tooltips (html or onclick popup)
  58. print "\n/* JS CODE TO ENABLE Tooltips on all object with class classfortooltip */\n";
  59. print "jQuery(document).ready(function () {\n";
  60. if (empty($conf->dol_no_mouse_hover)) {
  61. print 'jQuery(".classfortooltip").tooltip({
  62. show: { collision: "flipfit", effect:"toggle", delay:50, duration: 20 },
  63. hide: { delay: 250, duration: 20 },
  64. tooltipClass: "mytooltip",
  65. content: function () {
  66. console.log("Return title for popup");
  67. return $(this).prop("title"); /* To force to get title as is */
  68. }
  69. });'."\n";
  70. }
  71. print '
  72. jQuery(".classfortooltiponclicktext").dialog({
  73. closeOnEscape: true, classes: { "ui-dialog": "highlight" },
  74. maxHeight: window.innerHeight-60, width: '.($conf->browser->layout == 'phone' ? max($_SESSION['dol_screenwidth'] - 20, 320) : 700).',
  75. modal: true,
  76. autoOpen: false
  77. }).css("z-index: 5000");
  78. jQuery(".classfortooltiponclick").click(function () {
  79. console.log("We click on tooltip for element with dolid="+$(this).attr(\'dolid\'));
  80. if ($(this).attr(\'dolid\')) {
  81. obj=$("#idfortooltiponclick_"+$(this).attr(\'dolid\')); /* obj is a div component */
  82. obj.dialog("open");
  83. return false;
  84. }
  85. });'."\n";
  86. print "});\n";
  87. // Wrapper to manage dropdown
  88. if (!defined('JS_JQUERY_DISABLE_DROPDOWN')) {
  89. print "\n/* JS CODE TO ENABLE dropdown (hamburger, linkto, ...) */\n";
  90. print '
  91. jQuery(document).ready(function () {
  92. var lastopendropdown = null;
  93. // Click onto the link "link to" or "hamburger", toggle dropdown
  94. $(document).on(\'click\', \'.dropdown dt a\', function () {
  95. console.log("toggle dropdown dt a");
  96. //$(this).parent().parent().find(\'dd ul\').slideToggle(\'fast\');
  97. $(this).parent().parent().find(\'dd ul\').toggleClass("open");
  98. if ($(this).parent().parent().find(\'dd ul\').hasClass("open")) {
  99. lastopendropdown = $(this).parent().parent().find(\'dd ul\');
  100. //console.log(lastopendropdown);
  101. } else {
  102. // We closed the dropdown for hamburger selectfields
  103. if ($("input:hidden[name=formfilteraction]").val() == "listafterchangingselectedfields") {
  104. console.log("resubmit the form saved into lastopendropdown after clicking on hamburger");
  105. //$(".dropdown dt a").parents(\'form:first\').submit();
  106. //$(".dropdown dt a").closest("form").submit();
  107. lastopendropdown.closest("form").submit();
  108. }
  109. }
  110. // Note: Did not find a way to get exact height (value is update at exit) so i calculate a generic from nb of lines
  111. heigthofcontent = 21 * $(this).parent().parent().find(\'dd div ul li\').length;
  112. if (heigthofcontent > 300) heigthofcontent = 300; // limited by max-height on css .dropdown dd ul
  113. posbottom = $(this).parent().parent().find(\'dd\').offset().top + heigthofcontent + 8;
  114. var scrollBottom = $(window).scrollTop() + $(window).height();
  115. diffoutsidebottom = (posbottom - scrollBottom);
  116. console.log("heigthofcontent="+heigthofcontent+", diffoutsidebottom (posbottom="+posbottom+" - scrollBottom="+scrollBottom+") = "+diffoutsidebottom);
  117. if (diffoutsidebottom > 0)
  118. {
  119. pix = "-"+(diffoutsidebottom+8)+"px";
  120. console.log("We reposition top by "+pix);
  121. $(this).parent().parent().find(\'dd\').css("top", pix);
  122. }
  123. });
  124. // Click on a link into the popup "link to" or other dropdown that ask to close drop down on element click, so close dropdown
  125. $(".dropdowncloseonclick").on(\'click\', function () {
  126. console.log("Link has class dropdowncloseonclick, so we close/hide the popup ul");
  127. //$(this).parent().parent().hide(); // $(this).parent().parent() is ul
  128. $(this).parent().parent().removeClass("open"); // $(this).parent().parent() is ul
  129. });
  130. // Click outside of any dropdown
  131. $(document).bind(\'click\', function (e) {
  132. var $clicked = $(e.target); // This is element we click on
  133. if (!$clicked.parents().hasClass("dropdown")) {
  134. //console.log("close dropdown dd ul - we click outside");
  135. //$(".dropdown dd ul").hide();
  136. $(".dropdown dd ul").removeClass("open");
  137. if ($("input:hidden[name=formfilteraction]").val() == "listafterchangingselectedfields") {
  138. console.log("resubmit form saved into lastopendropdown after clicking outside of dropdown and having change selectlist from selectlist field of hamburger dropdown");
  139. //$(".dropdown dt a").parents(\'form:first\').submit();
  140. //$(".dropdown dt a").closest("form").submit();
  141. lastopendropdown.closest("form").submit();
  142. }
  143. }
  144. });
  145. });
  146. ';
  147. }
  148. // Wrapper to manage document_preview
  149. if ($conf->browser->layout != 'phone') {
  150. print "\n/* JS CODE TO ENABLE document_preview */\n"; // Function document_preview is into header
  151. print '
  152. jQuery(document).ready(function () {
  153. jQuery(".documentpreview").click(function () {
  154. console.log("We click on preview for element with href="+$(this).attr(\'href\')+" mime="+$(this).attr(\'mime\'));
  155. document_preview($(this).attr(\'href\'), $(this).attr(\'mime\'), \''.dol_escape_js($langs->transnoentities("Preview")).'\');
  156. return false;
  157. });
  158. });
  159. ' . "\n";
  160. }
  161. // Code to manage reposition
  162. print "\n/* JS CODE TO ENABLE reposition management (does not work if a redirect is done after action of submission) */\n";
  163. print '
  164. jQuery(document).ready(function() {
  165. /* If page_y set, we set scollbar with it */
  166. page_y=getParameterByName(\'page_y\', 0); /* search in GET parameter */
  167. if (page_y == 0) page_y = jQuery("#page_y").text(); /* search in POST parameter that is filed at bottom of page */
  168. if (page_y > 0)
  169. {
  170. console.log("page_y found is "+page_y);
  171. $(\'html, body\').scrollTop(page_y);
  172. }
  173. /* Set handler to add page_y param on output (click on href links or submit button) */
  174. jQuery(".reposition").click(function() {
  175. var page_y = $(document).scrollTop();
  176. if (page_y > 0)
  177. {
  178. if (this.href)
  179. {
  180. console.log("We click on tag with .reposition class. this.ref was "+this.href);
  181. var hrefarray = this.href.split("#", 2);
  182. hrefarray[0]=hrefarray[0].replace(/&page_y=(\d+)/, \'\'); /* remove page_y param if already present */
  183. this.href=hrefarray[0]+\'&page_y=\'+page_y;
  184. console.log("We click on tag with .reposition class. this.ref is now "+this.href);
  185. }
  186. else
  187. {
  188. console.log("We click on tag with .reposition class but element is not an <a> html tag, so we try to update input form field with name=page_y with value "+page_y);
  189. jQuery("input[type=hidden][name=page_y]").val(page_y);
  190. }
  191. }
  192. });
  193. });'."\n";
  194. print "\n/* JS CODE TO ENABLE ClipBoard copy paste*/\n";
  195. print 'jQuery(\'.clipboardCPShowOnHover\').hover(
  196. function() {
  197. console.log("We hover a value with a copy paste feature");
  198. $(this).children(".clipboardCPButton, .clipboardCPText").show();
  199. },
  200. function() {
  201. console.log("We hover out the value with a copy paste feature");
  202. $(this).children(".clipboardCPButton, .clipboardCPText").hide();
  203. }
  204. );';
  205. print 'jQuery(\'.clipboardCPButton, .clipboardCPValueToPrint\').click(function() {
  206. /* console.log(this.parentNode); */
  207. console.log("We click on a clipboardCPButton or clipboardCPValueToPrint class");
  208. if (window.getSelection) {
  209. selection = window.getSelection();
  210. range = document.createRange();
  211. range.selectNodeContents(this.parentNode.firstChild);
  212. selection.removeAllRanges();
  213. selection.addRange( range );
  214. }
  215. document.execCommand( \'copy\' );
  216. window.getSelection().removeAllRanges();
  217. /* Show message */
  218. var lastchild = this.parentNode.lastChild;
  219. var tmp = lastchild.innerHTML
  220. lastchild.innerHTML = \''.dol_escape_js($langs->trans('CopiedToClipboard')).'\';
  221. setTimeout(() => { lastchild.innerHTML = tmp; }, 1000);
  222. })'."\n";