app.js 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668
  1. /* For licensing terms, see /license.txt */
  2. // Load symfony routes in order to use it in a js
  3. const routes = require('../../public/js/fos_js_routes.json');
  4. import Routing from '../../vendor/friendsofsymfony/jsrouting-bundle/Resources/public/js/router.min.js';
  5. // Import Vue and Components
  6. import Vue from 'vue';
  7. import {VueConfig} from './VueConfig';
  8. import Example from './components/Example';
  9. import $ from 'jquery';
  10. window.jQuery = $;
  11. window.$ = $;
  12. Routing.setRoutingData(routes);
  13. const locale = document.querySelector('html').lang;
  14. require('./vendor');
  15. require('./main');
  16. // @todo rework url naming
  17. const homePublicUrl = Routing.generate('home') + 'public/';
  18. const legacyIndex = Routing.generate('legacy_index');
  19. const mainUrl = Routing.generate('web.main');
  20. const webAjax = Routing.generate('web.ajax');
  21. var ajax_url = webAjax + 'chat.ajax.php';
  22. var online_button = '<img src="' + homePublicUrl + 'img/statusonline.png">';
  23. var offline_button = '<img src="' + homePublicUrl + 'img/statusoffline.png">';
  24. /*var connect_lang = '{{ "ChatConnected"|get_lang }}';
  25. var disconnect_lang = '{{ "ChatDisconnected"|get_lang }}';*/
  26. var connect_lang = 'ChatConnected';
  27. var disconnect_lang = 'ChatDisconnected';
  28. $(function () {
  29. if (document.getElementById('app_header')) {
  30. // Create Vue Application
  31. new Vue(
  32. Object.assign(VueConfig, {
  33. el: '#app_header',
  34. components: {Example},
  35. data() {
  36. return {
  37. chamilo: ''
  38. }
  39. },
  40. methods: {
  41. getConsole() {
  42. console.log("Hello Vuejs");
  43. }
  44. }, created() {
  45. this.chamilo = "Hello Chamilo";
  46. this.getConsole();
  47. console.log(this.chamilo);
  48. }
  49. })
  50. );
  51. }
  52. var webCidReq = '&cidReq=' + $('body').attr('data-course-code');
  53. window.webCidReq = webCidReq;
  54. $("#menu_courses").click(function(){
  55. return false;
  56. });
  57. $("#menu_social").click(function(){
  58. return false;
  59. });
  60. $("#menu_administrator").click(function(){
  61. return false;
  62. });
  63. var isInCourse = $("body").data("in-course");
  64. if (isInCourse == true) {
  65. var courseCode = $("body").data("course-code");
  66. var logOutUrl = webAjax + 'course.ajax.php?a=course_logout&cidReq=' + courseCode;
  67. function courseLogout() {
  68. $.ajax({
  69. async: false,
  70. url: logOutUrl,
  71. success: function (data) {
  72. return 1;
  73. }
  74. });
  75. }
  76. addMainEvent(window, 'unload', courseLogout ,false);
  77. }
  78. $("#open-view-list").click(function () {
  79. $("#student-list-work").fadeIn(300);
  80. });
  81. $("#closed-view-list").click(function () {
  82. $("#student-list-work").fadeOut(300);
  83. });
  84. // Removes the yellow input in Chrome
  85. if (navigator.userAgent.toLowerCase().indexOf("chrome") >= 0) {
  86. $(window).on("load", function () {
  87. $('input:-webkit-autofill').each(function () {
  88. var text = $(this).val();
  89. var name = $(this).attr('name');
  90. $(this).after(this.outerHTML).remove();
  91. $('input[name=' + name + ']').val(text);
  92. });
  93. });
  94. }
  95. // Start modals
  96. // class='ajax' loads a page in a modal
  97. $('body').on('click', 'a.ajax', function (e) {
  98. e.preventDefault();
  99. var contentUrl = this.href,
  100. loadModalContent = $.get(contentUrl),
  101. self = $(this);
  102. $.when(loadModalContent).done(function (modalContent) {
  103. var modalDialog = $('#global-modal').find('.modal-dialog'),
  104. modalSize = self.data('size') || get_url_params(contentUrl, 'modal_size'),
  105. modalWidth = self.data('width') || get_url_params(contentUrl, 'width'),
  106. modalTitle = self.data('title') || ' ';
  107. modalDialog.removeClass('modal-lg modal-sm').css('width', '');
  108. if (modalSize && modalSize.length != 0) {
  109. switch (modalSize) {
  110. case 'lg':
  111. modalDialog.addClass('modal-lg');
  112. break;
  113. case 'sm':
  114. modalDialog.addClass('modal-sm');
  115. break;
  116. }
  117. } else if (modalWidth) {
  118. modalDialog.css('width', modalWidth + 'px');
  119. }
  120. $('#global-modal').find('.modal-title').text(modalTitle);
  121. $('#global-modal').find('.modal-body').html(modalContent);
  122. $('#global-modal').modal('show');
  123. });
  124. });
  125. $('#global-modal').on('hidden.bs.modal', function () {
  126. jQuery(".embed-responsive").find('iframe').remove();
  127. });
  128. // Expands an image modal
  129. $('a.expand-image').on('click', function (e) {
  130. e.preventDefault();
  131. var title = $(this).attr('title');
  132. var image = new Image();
  133. image.onload = function () {
  134. if (title) {
  135. $('#expand-image-modal').find('.modal-title').text(title);
  136. } else {
  137. $('#expand-image-modal').find('.modal-title').html('&nbsp;');
  138. }
  139. $('#expand-image-modal').find('.modal-body').html(image);
  140. $('#expand-image-modal').modal({
  141. show: true
  142. });
  143. };
  144. image.src = this.href;
  145. });
  146. // Delete modal
  147. $('#confirm-delete').on('show.bs.modal', function (e) {
  148. $(this).find('.btn-ok').attr('href', $(e.relatedTarget).data('href'));
  149. //var message = '{{ 'AreYouSureToDeleteJS' | get_lang }}: <strong>' + $(e.relatedTarget).data('item-title') + '</strong>';
  150. var message = 'AreYouSureToDeleteJS : <strong>' + $(e.relatedTarget).data('item-title') + '</strong>';
  151. if ($(e.relatedTarget).data('item-question')) {
  152. message = $(e.relatedTarget).data('item-question');
  153. }
  154. $('.debug-url').html(message);
  155. });
  156. // End modals
  157. // old jquery.menu.js
  158. $('#navigation a').stop().animate({
  159. 'marginLeft':'50px'
  160. },1000);
  161. $('#navigation div').hover(
  162. function () {
  163. $('a',$(this)).stop().animate({
  164. 'marginLeft':'1px'
  165. },200);
  166. },
  167. function () {
  168. $('a',$(this)).stop().animate({
  169. 'marginLeft':'50px'
  170. },200);
  171. }
  172. );
  173. /* Make responsive image maps */
  174. //$('map').imageMapResize();
  175. jQuery.fn.filterByText = function (textbox) {
  176. return this.each(function () {
  177. var select = this;
  178. var options = [];
  179. $(select).find('option').each(function () {
  180. options.push({value: $(this).val(), text: $(this).text()});
  181. });
  182. $(select).data('options', options);
  183. $(textbox).bind('change keyup', function () {
  184. var options = $(select).empty().data('options');
  185. var search = $.trim($(this).val());
  186. var regex = new RegExp(search, "gi");
  187. $.each(options, function (i) {
  188. var option = options[i];
  189. if (option.text.match(regex) !== null) {
  190. $(select).append(
  191. $('<option>').text(option.text).val(option.value)
  192. );
  193. }
  194. });
  195. });
  196. });
  197. };
  198. $(".black-shadow").mouseenter(function () {
  199. $(this).addClass('hovered-course');
  200. }).mouseleave(function () {
  201. $(this).removeClass('hovered-course');
  202. });
  203. $("[data-toggle=popover]").each(function (i, obj) {
  204. $(this).popover({
  205. html: true,
  206. content: function () {
  207. var id = $(this).attr('id');
  208. return $('#popover-content-' + id).html();
  209. }
  210. });
  211. });
  212. $('.scrollbar-inner').scrollbar();
  213. // Date time settings.
  214. moment.locale(locale);
  215. $.datepicker.setDefaults($.datepicker.regional[locale]);
  216. $.datepicker.regional["local"] = $.datepicker.regional[locale];
  217. // Fix old calls of "inc/lib/mediaplayer/player.swf" and convert to <audio> tag, then rendered by media element js
  218. // see BT#13405
  219. $('embed').each(function () {
  220. var flashVars = $(this).attr('flashvars');
  221. if (flashVars && flashVars.indexOf("file") == -1) {
  222. var audioId = Math.floor(Math.random() * 99999);
  223. flashVars = flashVars.replace('&autostart=false', '');
  224. flashVars = flashVars.replace('&autostart=true', '');
  225. var audioDiv = '<audio id="'+audioId+'" controls="controls" style="width:400px;" width:"400px;" src="'+flashVars+'" ><source src="'+flashVars+'" type="audio/mp3" ></source></audio>';
  226. $(this).hide();
  227. $(this).after(audioDiv);
  228. }
  229. });
  230. // Chosen select
  231. $(".chzn-select").chosen({
  232. disable_search_threshold: 10,
  233. /*no_results_text: '{{ 'SearchNoResultsFound' | get_lang | escape('js') }}',
  234. placeholder_text_multiple: '{{ 'SelectSomeOptions' | get_lang | escape('js') }}',
  235. placeholder_text_single: '{{ 'SelectAnOption' | get_lang | escape('js') }}',*/
  236. width: "100%"
  237. });
  238. // Bootstrap tabs.
  239. $('.tab_wrapper .nav a').on('click', function (e) {
  240. e.preventDefault()
  241. $(this).tab('show')
  242. });
  243. // Fixes bug when loading links inside a tab.
  244. $('.tab_wrapper .tab-pane a').unbind();
  245. /**
  246. * Advanced options
  247. * Usage
  248. * <a id="link" href="url">Advanced</a>
  249. * <div id="link_options">
  250. * hidden content :)
  251. * </div>
  252. * */
  253. $(".advanced_options").on("click", function (event) {
  254. event.preventDefault();
  255. var id = $(this).attr('id') + '_options';
  256. $("#" + id).toggle();
  257. if ($("#card-container").height() > 700) {
  258. $("#card-container").css("height", "auto");
  259. } else {
  260. $("#card-container").css("height", "100vh");
  261. }
  262. if ($("#column-left").hasClass("col-md-12")) {
  263. $("#column-left").removeClass('col-md-12');
  264. $("#column-right").removeClass('col-md-12');
  265. $("#column-right").addClass('col-md-4');
  266. $("#column-left").addClass('col-md-8');
  267. } else {
  268. $("#column-left").removeClass('col-md-8');
  269. $("#column-right").removeClass('col-md-4');
  270. $("#column-left").addClass('col-md-12');
  271. $("#column-right").addClass('col-md-12');
  272. }
  273. ;
  274. if ($("#preview_course_add_course").length >= 0) {
  275. $("#preview_course_add_course").toggle();
  276. }
  277. });
  278. /**
  279. * <a class="advanced_options_open" href="http://" rel="div_id">Open</a>
  280. * <a class="advanced_options_close" href="http://" rel="div_id">Close</a>
  281. * <div id="div_id">Div content</div>
  282. * */
  283. $(".advanced_options_open").on("click", function (event) {
  284. event.preventDefault();
  285. var id = $(this).attr('rel');
  286. $("#" + id).show();
  287. });
  288. $(".advanced_options_close").on("click", function (event) {
  289. event.preventDefault();
  290. var id = $(this).attr('rel');
  291. $("#" + id).hide();
  292. });
  293. // Adv multi-select search input.
  294. $('.select_class_filter').each(function () {
  295. var inputId = $(this).attr('id');
  296. inputId = inputId.replace('-filter', '');
  297. $("#" + inputId).filterByText($("#" + inputId + "-filter"));
  298. });
  299. // Mediaelement
  300. //if ( {{ show_media_element }} == 1) {
  301. // $('video:not(.skip), audio:not(.skip)').mediaelementplayer({
  302. // pluginPath: _p.web + 'web/assets/mediaelement/build/',
  303. // //renderers: ['html5', 'flash_video', 'native_flv'],
  304. // features: ['{{ video_features }}'],
  305. // success: function(mediaElement, originalNode, instance) {
  306. // },
  307. // vrPath: _p.web + 'web/assets/vrview/build/vrview.js'
  308. // });
  309. //}
  310. // Table highlight.
  311. $("form .data_table input:checkbox").click(function () {
  312. if ($(this).is(":checked")) {
  313. $(this).parentsUntil("tr").parent().addClass("row_selected");
  314. } else {
  315. $(this).parentsUntil("tr").parent().removeClass("row_selected");
  316. }
  317. });
  318. // Tool tip (in exercises)
  319. var tip_options = {
  320. placement: 'right'
  321. };
  322. $('.boot-tooltip').tooltip(tip_options);
  323. $('.star-rating li a').on('click', function (event) {
  324. var id = $(this).parents('ul').attr('id');
  325. //$('#vote_label2_' + id).html("{{'Loading'|get_lang}}");
  326. $('#vote_label2_' + id).html("loading");
  327. $.ajax({
  328. url: $(this).attr('data-link'),
  329. success: function (data) {
  330. $("#rating_wrapper_" + id).html(data);
  331. if (data == 'added') {
  332. //$('#vote_label2_' + id).html("{{'Saved'|get_lang}}");
  333. }
  334. if (data == 'updated') {
  335. //$('#vote_label2_' + id).html("{{'Saved'|get_lang}}");
  336. }
  337. }
  338. });
  339. });
  340. $("#notifications").load(webAjax + "online.ajax.php?a=get_users_online");
  341. });
  342. $(document).scroll(function () {
  343. var valor = $('body').outerHeight() - 700;
  344. if ($(this).scrollTop() > 100) {
  345. $('.bottom_actions').addClass('bottom_actions_fixed');
  346. } else {
  347. $('.bottom_actions').removeClass('bottom_actions_fixed');
  348. }
  349. if ($(this).scrollTop() > valor) {
  350. $('.bottom_actions').removeClass('bottom_actions_fixed');
  351. } else {
  352. $('.bottom_actions').addClass('bottom_actions_fixed');
  353. }
  354. //Exercise warning fixed at the top
  355. var fixed = $("#exercise_clock_warning");
  356. if (fixed.length) {
  357. if (!fixed.attr('data-top')) {
  358. // If already fixed, then do nothing
  359. if (fixed.hasClass('subnav-fixed')) return;
  360. // Remember top position
  361. var offset = fixed.offset();
  362. fixed.attr('data-top', offset.top);
  363. fixed.css('width', '100%');
  364. }
  365. if (fixed.attr('data-top') - fixed.outerHeight() <= $(this).scrollTop()) {
  366. fixed.addClass('navbar-fixed-top');
  367. fixed.css('width', '100%');
  368. } else {
  369. fixed.removeClass('navbar-fixed-top');
  370. fixed.css('width', '100%');
  371. }
  372. }
  373. // Admin -> Settings toolbar.
  374. if ($('body').width() > 959) {
  375. if ($('.new_actions').length) {
  376. if (!$('.new_actions').attr('data-top')) {
  377. // If already fixed, then do nothing
  378. if ($('.new_actions').hasClass('new_actions-fixed')) return;
  379. // Remember top position
  380. var offset = $('.new_actions').offset();
  381. var more_top = 0;
  382. if ($('.subnav').hasClass('new_actions-fixed')) {
  383. more_top = 50;
  384. }
  385. $('.new_actions').attr('data-top', offset.top + more_top);
  386. }
  387. // Check if the height is enough before fixing the icons menu (or otherwise removing it)
  388. // Added a 30px offset otherwise sometimes the menu plays ping-pong when scrolling to
  389. // the bottom of the page on short pages.
  390. if ($('.new_actions').attr('data-top') - $('.new_actions').outerHeight() <= $(this).scrollTop() + 30) {
  391. $('.new_actions').addClass('new_actions-fixed');
  392. } else {
  393. $('.new_actions').removeClass('new_actions-fixed');
  394. }
  395. }
  396. }
  397. });
  398. function get_url_params(q, attribute)
  399. {
  400. var hash;
  401. if (q != undefined) {
  402. q = q.split('&');
  403. for (var i = 0; i < q.length; i++) {
  404. hash = q[i].split('=');
  405. if (hash[0] == attribute) {
  406. return hash[1];
  407. }
  408. }
  409. }
  410. }
  411. function setCheckbox(value, table_id)
  412. {
  413. var checkboxes = $("#" + table_id + " input:checkbox");
  414. $.each(checkboxes, function (index, checkbox) {
  415. checkbox.checked = value;
  416. if (value) {
  417. $(checkbox).parentsUntil("tr").parent().addClass("row_selected");
  418. } else {
  419. $(checkbox).parentsUntil("tr").parent().removeClass("row_selected");
  420. }
  421. });
  422. return false;
  423. }
  424. function action_click(element, table_id)
  425. {
  426. var d = $("#" + table_id);
  427. if (!confirm('ConfirmYourChoice')) {
  428. //if (!confirm('{{ "ConfirmYourChoice"|get_lang }}')) {
  429. return false;
  430. } else {
  431. var action = $(element).attr("data-action");
  432. $('#' + table_id + ' input[name="action"] ').attr("value", action);
  433. d.submit();
  434. return false;
  435. }
  436. }
  437. /**
  438. * Generic function to replace the deprecated jQuery toggle function
  439. * @param inId : id of block to hide / unhide
  440. * @param inIdTxt : id of the button
  441. * @param inTxtHide : text one of the button
  442. * @param inTxtUnhide : text two of the button
  443. * @todo : allow to detect if text is from a button or from a <a>
  444. */
  445. function hideUnhide(inId, inIdTxt, inTxtHide, inTxtUnhide)
  446. {
  447. if ($('#'+inId).css("display") == "none") {
  448. $('#'+inId).show(400);
  449. $('#'+inIdTxt).attr("value", inTxtUnhide);
  450. } else {
  451. $('#'+inId).hide(400);
  452. $('#'+inIdTxt).attr("value", inTxtHide);
  453. }
  454. }
  455. function expandColumnToogle(buttonSelector, col1Info, col2Info)
  456. {
  457. $(buttonSelector).on('click', function (e) {
  458. e.preventDefault();
  459. col1Info = $.extend({
  460. selector: '',
  461. width: 4
  462. }, col1Info);
  463. col2Info = $.extend({
  464. selector: '',
  465. width: 8
  466. }, col2Info);
  467. if (!col1Info.selector || !col2Info.selector) {
  468. return;
  469. }
  470. var col1 = $(col1Info.selector),
  471. col2 = $(col2Info.selector);
  472. $('#expand').toggleClass('hide');
  473. $('#contract').toggleClass('hide');
  474. if (col2.is('.col-md-' + col2Info.width)) {
  475. col2.removeClass('col-md-' + col2Info.width).addClass('col-md-12');
  476. col1.removeClass('col-md-' + col1Info.width).addClass('hide');
  477. return;
  478. }
  479. col2.removeClass('col-md-12').addClass('col-md-' + col2Info.width);
  480. col1.removeClass('hide').addClass('col-md-' + col1Info.width);
  481. });
  482. }
  483. // Load ckeditor plugins
  484. if (typeof CKEDITOR !== 'undefined') {
  485. // External plugins not part of the default Ckeditor package.
  486. var plugins = [
  487. 'asciimath',
  488. 'asciisvg',
  489. 'audio',
  490. 'ckeditor_wiris',
  491. 'dialogui',
  492. 'glossary',
  493. 'leaflet',
  494. 'mapping',
  495. 'maximize',
  496. 'mathjax',
  497. 'oembed',
  498. 'toolbar',
  499. 'toolbarswitch',
  500. 'video',
  501. 'wikilink',
  502. 'wordcount',
  503. 'youtube',
  504. 'flash',
  505. 'inserthtml',
  506. 'image2_chamilo'
  507. ];
  508. plugins.forEach(function (plugin) {
  509. CKEDITOR.plugins.addExternal(
  510. plugin,
  511. mainUrl + 'inc/lib/javascript/ckeditor/plugins/' + plugin + '/'
  512. );
  513. });
  514. /**
  515. * Function use to load templates in a div
  516. **/
  517. var showTemplates = function (ckeditorName) {
  518. var editorName = 'content';
  519. if (ckeditorName && ckeditorName.length > 0) {
  520. editorName = ckeditorName;
  521. }
  522. CKEDITOR.editorConfig(CKEDITOR.config);
  523. CKEDITOR.loadTemplates(CKEDITOR.config.templates_files, function (a) {
  524. var templatesConfig = CKEDITOR.getTemplates("default");
  525. var $templatesUL = $("<ul>");
  526. if (templatesConfig) {
  527. $.each(templatesConfig.templates, function () {
  528. var template = this;
  529. var $templateLi = $("<li>");
  530. var templateHTML = "<img src=\"" + templatesConfig.imagesPath + template.image + "\" ><div>";
  531. templateHTML += "<b>" + template.title + "</b>";
  532. if (template.description) {
  533. templateHTML += "<div class=description>" + template.description + "</div>";
  534. }
  535. templateHTML += "</div>";
  536. $("<a>", {
  537. href: "#",
  538. html: templateHTML,
  539. click: function (e) {
  540. e.preventDefault();
  541. if (CKEDITOR.instances[editorName]) {
  542. CKEDITOR.instances[editorName].setData(template.html, function () {
  543. this.checkDirty();
  544. });
  545. }
  546. }
  547. }).appendTo($templateLi);
  548. $templatesUL.append($templateLi);
  549. });
  550. }
  551. $templatesUL.appendTo("#frmModel");
  552. });
  553. };
  554. }
  555. function addMainEvent(elm, evType, fn, useCapture)
  556. {
  557. if (elm.addEventListener) {
  558. elm.addEventListener(evType, fn, useCapture);
  559. return true;
  560. } else if (elm.attachEvent) {
  561. elm.attachEvent('on' + evType, fn);
  562. } else {
  563. elm['on'+evType] = fn;
  564. }
  565. }
  566. function copyTextToClipBoard(elementId)
  567. {
  568. /* Get the text field */
  569. var copyText = document.getElementById(elementId);
  570. /* Select the text field */
  571. copyText.select();
  572. /* Copy the text inside the text field */
  573. document.execCommand('copy');
  574. }
  575. // Expose functions to be use inside chamilo.
  576. // @todo check if there's a better way to expose functions.
  577. window.expandColumnToogle = expandColumnToogle;
  578. window.get_url_params = get_url_params;
  579. window.setCheckbox = setCheckbox;
  580. window.action_click = action_click;
  581. window.hideUnhide = hideUnhide;
  582. window.addMainEvent = addMainEvent;
  583. window.showTemplates = showTemplates;