1// general 2var controller; 3var id; 4var class_id; 5 6// lessons 7var current_lesson_id; 8var unhide_text; 9var hide_text; 10var confirm_text; 11 12// assignments 13var assignment_id; 14 15// quiz configure 16var configure_controller; 17var configure_id; 18 19// questions configure 20var questions_controller; 21var questions_id; 22 23// user popups 24var disable_user_popups_flag = false; 25var user_timer = null; 26var user_href = null; 27 28// toggle 29var last_toggled_id = null; 30 31// navigation 32var hover_timer = null; 33var hover_timer_triggered = false; 34var hover_tab_id; 35var hover_class_id; 36var hover_student_class_id; 37 38// click to chat 39var chat_alert_displayed = false; 40var loaded_sound_manager = false; 41 42// new mobile 43var menuStatus; 44var shiftContent; 45var contentHeight; 46var menuContentHeight; 47 48// close facebox after x sec if wanted 49var FACEBOX_CLOSING_TIME = 2500; 50 51// for tinymce and popup messages with ajax 52var tinyPop = true; 53var closeAlertTimer; 54 55//mobile app notifications counter 56var mobile_messages_count = 0; 57var mobile_notifications_count = 0; 58 59// widget panel original 60var context_uri = false; 61 62// edit tool id 63var tool_to_edit_id = null; 64 65// transfer variables 66var select_all_learners = null; 67var select_learners = null; 68 69// keep base controller 70var base_controller = null; 71 72// stacked picker 73var stacked_picker = null; 74 75// copilot picker 76var copilot_picker = null; 77var copilot_callback = null; 78 79// session timeout 80var pause_session_timeout = false; 81 82// new mobile initialization 83 84function initScrollers() { 85 menuScroller = new iScroll('menu-content', {vScrollbar: false}); 86 contentScroller = new iScroll('phone-body', {vScrollbar: false}); 87} 88 89function init_container_height(){ 90 setTimeout(function(){ 91 var container = $('.user #contentWrap'); 92 var sub_head = $('#contentHeader').length ? $('#contentHeader').outerHeight() : 0; 93 var header = $('header').length ? $('header').outerHeight() : 0; 94 var footer = $('footer').length ? $('footer').outerHeight() : 0; 95 if (navigator.appVersion.indexOf('Trident') > 0) { 96 // Will exclude Edge and target IE11 97 container = $('#contentWrap'); 98 header = $('.catalog_class').length > 0 && $('.transparent_header').length == 0 ? $('header').outerHeight() : 0; 99 } 100 container.css('min-height', 'calc(100vh - ' + (sub_head + header + footer) + 'px)'); 101 }, 100); 102} 103 104function removeScrollers() { 105 menuScroller.destroy(); 106 contentScroller.destroy(); 107 menuScroller = null; 108 contentScroller = null; 109} 110 111function refreshScrollers() { 112 menuScroller.refresh(); 113 contentScroller.refresh(); 114} 115 116$(function() { 117 var original_init = $.prototype.init; 118 $.prototype.init = function (e, t) { 119 try { 120 $.extend(this, new original_init(e == '#' ? [] : e, t)); 121 } catch(error) { 122 } 123 }; 124 $.prototype.init.prototype = original_init.prototype; 125 //init_container_height(); 126}); 127 128function updateHeight() { 129 shiftContent = (is_mobile_app_mode() ? globalWindowWidth : $(window).width()) - 70; 130 contentHeight = (is_mobile_app_mode() ? globalWindowHeight : $(window).height()) - $('#phone-header').height() - $('#phone-footer').height() + 3; 131 menuContentHeight = (is_mobile_app_mode() ? globalWindowHeight : $(window).height()) - $('#menu-content').offset().top; 132 133 $("#menu").width(shiftContent); 134 $("#mnu-header .nav_search").width(shiftContent - 80); 135 136 $('#phone-body').css('height', contentHeight + 'px'); 137 $('#menu').css('height', (is_mobile_app_mode() ? globalWindowHeight : $(window).height()) + 'px'); 138 $('#menu-content').css('height', menuContentHeight + 'px'); 139 140 refreshScrollers(); 141} 142 143function init_mobile() { 144 if(!is_mobile_app_mode()){ 145 $(window).resize(updateHeight); 146 } 147 148 setTimeout(function() { 149 updateHeight(); 150 }, 500); 151 152 $("#menu").css('display', 'none'); 153 154 $("#btn-menu").click(function() { 155 if (menuStatus != true) { 156 $("#menu").css('display', 'block'); 157 158 $("#wrapper").animate({ 159 left : shiftContent + "px" 160 }, 300, function() { 161 menuStatus = true; 162 refreshScrollers(); 163 }); 164 165 $("#wrapper #phone-header").animate({ 166 left : shiftContent + "px" 167 }, 300); 168 $("#wrapper #phone-footer").animate({ 169 left : shiftContent + "px" 170 }, 300); 171 172 return false;
173 } else { 174 $("#wrapper").animate({ 175 left : "0" 176 }, 300, function() { 177 menuStatus = false; 178 }); 179 180 $("#wrapper #phone-header").animate({ 181 left : "0" 182 }, 300); 183 184 $("#wrapper #phone-footer").animate({ 185 left : "0" 186 }, 300, function() { 187 $("#menu").css('display', 'none'); 188 }); 189 190 return false; 191 } 192 }); 193 194 initScrollers(); 195 refreshScrollers(); 196} 197 198function init_log_in() { 199 $(".signin").click(function(e) { 200 e.preventDefault(); 201 $("fieldset#signin_menu").toggle(); 202 $(".signin").toggleClass("menu-open"); 203 $('#userid').focus(); 204 }); 205 206 $("fieldset#signin_menu").mouseup(function() { 207 return false; 208 }); 209 210 $(document).mouseup(function(e) { 211 if ($(e.target).parent("a.signin").length == 0) { 212 $(".signin").removeClass("menu-open"); 213 $("fieldset#signin_menu").hide(); 214 } 215 }); 216} 217 218// Minimum content height 219 220function init_min_height() { 221 if($('.carouselWrap').length == 0){ 222 update_min_height(); 223 $(window).resize(update_min_height); 224 } 225 226 //Overriding the initial properties from default-styles.css 227 /*$('.catalog_class footer').show(); 228 $('body.catalog_class').css('overflow', 'auto');*/ 229} 230 231function update_min_height() { 232 var header = $('header'); 233 var footer = $('footer'); 234 var windowHeight = $(window).height() - header.height() - footer.height(); 235 if($('#calendar2').length && $('table.calendar').hasClass('monthly')) { 236 windowHeight = $('#calendar2').outerHeight() + 30 > windowHeight ? $('#calendar2').outerHeight() + 30 : windowHeight; 237 } 238 // Thin main menu height 239 if ($('nav#leftColumn ol.thinMainNav').length) 240 $('nav#leftColumn ol.thinMainNav').height($(window).height() - $('header').height()); 241 242 if(typeof globalWindowWidth == 'undefined'){ 243 globalWindowWidth = $(window).width(); 244 } 245 246 if (/iPad/i.test(navigator.userAgent) && globalWindowWidth > 768 && $('.hasEditor').length) { 247 $('#wrapper').css('overflow', 'hidden'); 248 } 249 250 resizeFixedLeftColumn(); 251 if ($('body').hasClass('section_nav_page')) section_nav_height(); 252} 253 254// Fixed left column height 255 256function set_vars(){ 257 window.first_resizeFixedLeftColumn_call = false; 258 window.loadFixedLeftColumn = true; 259// Vars for fixed grading column defined outside function to prevent shudder in IE11 and Edge 260 if ($('.grading_fixed_col').length > 0) { 261 window.rightColumn_top = $('.rightColumn').offset().top; 262 position_of_topbar = $('#fixedSectionHeader').css('position') 263 let left_column = document.body.classList.contains('evo') ? $('.leftColumn') : $('#leftColumn'); 264 //this condition is to be executed only on the old ui. 265 if(position_of_topbar == 'fixed' || position_of_topbar == 'sticky'){ 266 window.fixed_header_bottom = left_column.offset().top + $('#fixedSectionHeader').outerHeight(); 267 } 268 } 269} 270set_vars(); 271$(window).on('loadcomplete', function(){ 272 //added to fix issue where varible where not updated for ajax pages 273 set_vars(); 274}); 275function fixedLeftColumnHeight(leftcolumn_height) { 276 var fixed_nav_bottom = $(window).scrollTop() - ( $('footer').offset().top - $(window).height()); 277 278 if (fixed_nav_bottom > 0) { 279 // footer visible 280 if (is_mobile_device()) { 281 fixed_nav_bottom = fixed_nav_bottom + ((window.screen.availHeight - globalWindowHeight)/2) 282 } 283 $('#leftColumn').css({'height': leftcolumn_height - fixed_nav_bottom + 2, 'min-height': 0}); 284 } else { 285 $('#leftColumn').css('min-height', leftcolumn_height + 2); 286 } 287 288 if (document.querySelector("body.evo")) { 289 if ($('.ctr_user_cart #leftColumn').length != 0) { 290 $('#leftColumn').css({'height': leftcolumn_height - 60}); 291 } else { 292 $('#leftColumn').css({'height': leftcolumn_height - 20}); 293 } 294 } 295 296 if ($('nicescroll-rails').length == 0) 297 init_niceScroll() 298} 299 300function resizeFixedLeftColumn() { 301 if ($('body').hasClass('catalog_class') && $(window).width() >= 768) { 302 var header_height = ($('body').hasClass('transparent_header')) ? 0 : $('header').outerHeight(); 303 var leftcolumn_height = ($('body').hasClass('portal')) ? $(window).height() - $('.portal #contentHeader').outerHeight() - header_height : $(window).height() - header_height; 304 305 if (Excalibur.evo && $('body').hasClass('portal') && $('nav#leftColumn div#checkout_summary')) { 306 leftcolumn_height = $('footer').offset().top - $('.portal #contentHeader').outerHeight() - $(window).scrollTop() + 21; 307 } 308 309 // Set bottom of fixed left nav based on footer position 310 if (loadFixedLeftColumn == true) { 311 setTimeout(function(){ 312 fixedLeftColumnHeight(leftcolumn_height); 313 loadFixedLeftColumn = false 314 }, 100); 315 } else { 316 fixedLeftColumnHeight(leftcolumn_height) 317 } 318 } 319 320 // Fixed right column height 321 if ($('.grading_fixed_col').length > 0) { 322 if ($('.grading_fixed_col').css('opacity') == 0) { 323 $('.grading_fixed_col').css('opacity','1'); 324 } 325 326 if ($(window).width() >= 980) { 327 var scroll_pos = $('#contentWrap').outerHeight() - globalWindowHeight - $(window).scrollTop() + $('header').outerHeight(); 328 329 $('.grading_fixed_col, .column_resize_handle').css('top', right
329Column_top); 330 if ($('#fixedSectionHeader').hasClass('student') && (!document.querySelector("body.evo"))) { 331 // student view - change top according according to scroll position 332 var top_pos = $('.rightColumn').offset().top - $(window).scrollTop() - 14; 333 if (top_pos > fixed_header_bottom) { 334 $('.grading_fixed_col, .column_resize_handle').css('top', top_pos); 335 } else { 336 // highest top position 337 $('.grading_fixed_col, .column_resize_handle').css('top', fixed_header_bottom); 338 } 339 } 340 341 if (scroll_pos < 0) { 342 // Footer is visible 343 $('.grading_fixed_col, .column_resize_handle').css('bottom', - scroll_pos + 'px'); 344 } else { 345 // Footer isn't visible 346 $('.grading_fixed_col, .column_resize_handle').css('bottom', '0'); 347 } 348 } 349 } 350} 351$(window).scroll(function() { 352 if ($('body').hasClass('catalog_class') || $('.grading_fixed_col').length > 0) { 353 // Fix scroll position which sometimes breaks NiceScroll on page load. 354 if (!first_resizeFixedLeftColumn_call && $(window).scrollTop() > 0) { 355 $(window).scrollTop(0); 356 first_resizeFixedLeftColumn_call = true; 357 } 358 resizeFixedLeftColumn(); 359 } 360}); 361 362function init_niceScroll() { 363 // if ($('.grading_fixed_col').length > 0) { 364 // // Teacher rubric grading pages 365 // if (is_mobile_device()) { 366 // $(".grading_fixed_col, .grade-floating-rubric-scroll").css({'-webkit-overflow-scrolling':'touch'}); 367 // } else { 368 // $(".grading_fixed_col, .grade-floating-rubric-scroll").niceScroll({ 369 // cursorwidth: "7px", 370 // cursorcolor: "#000", 371 // cursoropacitymax: 0.4, 372 // autohidemode: ($('#fixedSectionHeader').hasClass('student') ? true : false), 373 // railpadding: {top: 2, right: 1, left: 1, bottom: 1}, 374 // nativeparentscrolling: false, 375 // railalign: (is_rtl_mode() ? 'left' : 'right') 376 // }); 377 // // Only force show the scrollbar on the teacher view 378 // if (!$('#fixedSectionHeader').hasClass('student')) { 379 // $('.nicescroll-rails-vr').addClass('do_not_hide'); 380 // } 381 // } 382 // } else { 383 // Catalog item and checkout pages 384 if (is_mobile_device()) { 385 $(".catalog_class #leftColumn").css({'overflow':'auto'}); 386 } else { 387 $(".catalog_class #leftColumn").niceScroll({ 388 cursorcolor: "#000", 389 cursoropacitymax: 0.4, 390 cursorborder:"1px solid transparent", 391 autohidemode: false, 392 railalign: (is_rtl_mode() ? 'left' : 'right') 393 }); 394 } 395 //} 396} 397 398// The action toolbar renders the right-aligned ribbon as .action-toolbar--right, 399// so both container classes have to be matched wherever the legacy one was. 400const MSG_SIBLING_PREFIX = 'div.info:not(.keepopen) + .pageHeading.mobile_only + '; 401const MSG_SIBLING_RIBBONS = MSG_SIBLING_PREFIX + '.optionsRibbon.optionsRight, ' + MSG_SIBLING_PREFIX + '.action-toolbar--right'; 402 403function msgHide(){ 404 $(MSG_SIBLING_RIBBONS).hide(); 405 406 if ($('body').hasClass('catalog_class') && $('div.alert_block.info:not(.keepopen)').length > 0 && $(window).width() > $('#wrapper').outerWidth()) { 407 $('.catalog_class').addClass('offscreen_nicescroll'); // Hide niceScroll while alert closes and page height changes 408 } 409 410 $('div.info:not(.keepopen)').animate({ 411 height: '0', opacity: '0' 412 }, 500, function () { 413 $(this).css('display', 'none'); 414 $(MSG_SIBLING_RIBBONS).css('top', 0).show(); 415 if ($('body').hasClass('catalog_class')) { 416 resizeFixedLeftColumn(); // Resize niceScroll scroll bar after page height change 417 $('.catalog_class').removeClass('offscreen_nicescroll'); // remove class 418 } 419 if ($('#fixedSectionHeader').length) { 420 resizeSectionHeader(true); 421 if ($('.grading_fixed_col').length) { 422 // reset grading column after alert is removed 423 rightColumn_top = $('.rightColumn').offset().top; 424 fixed_header_bottom = $('#leftColumn').offset().top + $('#fixedSectionHeader').outerHeight(); 425 resizeFixedLeftColumn(); 426 } 427 } 428 }); 429} 430 431// initialize sound manager 432 433function init_sound_manager(soundHandler) { 434 soundManager.setup({ 435 url: '/flash/soundmanager2.swf?2', 436 debugMode: false, 437 onready: function() { 438 loaded_sound_manager = true; 439 440 soundManager.createSound({ 441 id : 'user_sound', 442 url : '/audio/user.mp3' 443 }); 444 445 soundManager.createSound({ 446 id : 'message_sound', 447 url : '/audio/message.mp3' 448 }); 449 450 if (soundHandler){ 451 soundHandler(); 452 } 453 } 454 }); 455} 456 457// process tables for IE7 458 459function process_tables() { 460 $('td[colspan^="100"]').each(function(i) { 461 var width = 0; 462 463 $(this).parent().next().children().each(function(j) { 464 var colspan = $(this).attr('colspan'); 465 width += (colspan == null ? 1 : parseInt(colspan)); 466 }); 467 468 $(this).attr('colspan', width); 469 }); 470} 471 472// dynamic site width 473 474function update_site_width() { 475 var site_width = (is_mobile_app_mode() ? globalWindowWidth : $(window).width())
475- 26; 476 $('#footer_center').width(site_width); 477} 478 479function init_update_site_width() { 480 $('#main_content, #footer_center').css('max-width', (1400 - 26) + 'px'); // #main_content padding (24px) + #main_content border = 26 481 $('#logo_block').css('margin-left', 13 + 'px'); // half of padding + border above 482 $('#main_content').css('margin-left', '0px'); 483 $('#buttons_right, #main_content').css('margin-right', '0px'); 484 update_site_width(); 485 $(window).resize(update_site_width); 486} 487 488// navigation 489 490function init_navigation() { 491 if ($('html').hasClass("iPad")) { 492 $('#main_nav li').click(function(event) { 493 $(this).parent().find('.highlight').removeClass('highlight'); 494 $(this).siblings().find('.dropdown').hide(); 495 $(this).find('a:first').addClass('highlight'); 496 497 if ($(this).find(".dropdown").is(':hidden')) { 498 $(this).find(".dropdown").show(); 499 } else { 500 $(this).find(".dropdown").hide(); 501 $(this).parent().find('.highlight').removeClass('highlight'); 502 } 503 504 event.stopPropagation(); 505 }); 506 } else { 507 $('ul#main_nav > li').hover(function() { 508 $(this).find('a:first').addClass("highlight"); 509 $(this).find('.dropdown').stop(true, true).show(); 510 }, function() { 511 $(this).find('a:first').removeClass("highlight"); 512 $(this).find('.dropdown').stop(true, true).hide(); 513 }); 514 } 515 516 // click inside drop down on right 517 $('#advSearchHolder').click(function() { 518 if ($('.dropdownOn').length == 0) { 519 $('#advSearchHolder').removeClass('dropdownOff').addClass('dropdownOn'); 520 521 if ($('.advSearchOn').length != 0) { 522 $('.search').removeClass('advSearchOn').addClass('advSearchOff'); 523 } 524 525 return false; 526 } 527 }); 528 529 $('.adminDropdown').click(function(event) { 530 if ($(this).find(".header_dropdown").is(':hidden')) { 531 $(this).find(".header_dropdown").show(); 532 $('#leftColumn .dropdown_holder').removeClass('dropdownOff').addClass('dropdownOn'); 533 } else { 534 $(this).find(".header_dropdown").hide(); 535 $('#leftColumn .dropdown_holder').removeClass('dropdownOn').addClass('dropdownOff'); 536 } 537 538 event.stopPropagation(); 539 }); 540 541 $('.search').click(function(event) { 542 if ($('.advSearchOn').length == 0) { 543 $('.search').removeClass('advSearchOff').addClass('advSearchOn'); 544 545 if ($('.dropdownOn').length != 0) { 546 $('#advSearchHolder').removeClass('dropdownOn').addClass('dropdownOff'); 547 } 548 549 $('#search_phrase').focus(); 550 return false; 551 } 552 event.stopPropagation(); 553 }); 554 555 $("#wrapper").click(function() { 556 if ($('.dropdownOn').length != 0) { 557 $('.dropdown_holder').removeClass('dropdownOn').addClass('dropdownOff'); 558 $('#advSearchHolder').removeClass('dropdownOn').addClass('dropdownOff'); 559 $('#leftColumn .dropdown_holder').removeClass('dropdownOn').addClass('dropdownOff'); 560 $('.header_dropdown').hide(); 561 $('.assignment_type').removeClass('dropdownOn'); 562 } 563 564 if ($('.advSearchOn').length != 0) { 565 $('.search').removeClass('advSearchOn').addClass('advSearchOff'); 566 } 567 568 /* only for iPad */ 569 if ($('#main_nav a.highlight').length != 0) { 570 $('#main_nav .dropdown').hide(); 571 $('#main_nav a.highlight').removeClass('highlight'); 572 } 573 }); 574 575 /* drop down scrolling for IE6 */ 576 if ($.browser.msie && parseInt($.browser.version, 10) == 6) { 577 $('div.scroll ul').each(function() { 578 var $this = $(this); 579 580 if ($this.children('li').length > 10) { 581 $this.parent().css('height', '270px'); 582 } 583 }); 584 } 585} 586 587// open window 588 589function open_new_window(url){ 590 if(is_mobile_app_mode()){ 591 window.parent.postMessage("{\"method\": \"loadBrowser\", \"href\": \"" + url + "\"}", "*"); 592 }else { 593 window.open(url); 594 } 595} 596 597// date picker 598 599// Not the input's title: the helpers build that from model+attribute names ("event begin at"). 600function datepickerAriaLabel() { 601 return window.datepickerLabel || 'Date picker'; 602} 603 604// The div is a singleton shared with pickers built elsewhere, so release everything on close. 605function datepickerOpenFor(inputEl) { 606 const inst = $.datepicker._curInst; 607 return !!$.datepicker._datepickerShowing && !!inst && !!inst.input && inst.input[0] === inputEl; 608} 609 610function releaseSharedDatepickerState() { 611 const $shared = $('#ui-datepicker-div'); 612 $shared 613 .off('keydown.datepicker-accessibility') 614 .removeAttr('role') 615 .removeAttr('aria-label') 616 .removeData('focus-date') 617 .removeData('focus-nav') 618 .removeData('keyboard-nav'); 619 // Bound on the buttons and day cells, so the div's .off() above does not reach them. 620 $shared.find('.ui-datepicker-buttonpane button, td[data-handler="selectDay"] a') 621 .off('click.datepicker-accessibility'); 622 if (datepickerRedrawObserver) { datepickerRedrawObserver.disconnect(); datepickerRedrawObserver = null; } 623} 624 625function setDatepickerExpanded(inputEl, isOpen) { 626 const $input = $(inputEl); 627 // combobox because aria-expanded is not supported on the implicit textbox role. 628 $input.attr({ 'role': 'combobox', 'aria-haspopup': 'dialog', 'aria-expanded': isOpen ? 'true' : 'false' }); 629 if (isOpen) { $input.attr('aria-controls', 'ui-datepicker-div'); } 630 else { $input.removeAttr('aria-controls'); } 631 if (!isOpen) { $('#datepicker-announcer').removeData('last'); } 632} 633 634function datepickerMonthLabel(dpDiv) { 635 const $title = $(dpDiv).find('.ui-datepicker-title'); 636 if (!$title.length || $title.find('select').length) { return datepickerAriaLabel(); } 637 return $title.text().replace(/\s+/g, ' ').trim() || datepickerAriaLabel(); 638} 639 640function datepickerAnnouncer() { 641 let $announcer = $('#datepicker-announcer'); 642 if (!$announcer.length) {
643 $announcer = $('<div id="datepicker-announcer" class="sr-only" role="status" aria-live="polite"></div>').appendTo('body'); 644 } 645 return $announcer; 646} 647 648function announceDatepickerMonth(text) { 649 const $announcer = datepickerAnnouncer(); 650 if ($announcer.data('last') === text) { return; } 651 $announcer.data('last', text); 652 setTimeout(function() { $announcer.text(text); }, 0); 653} 654 655function restoreDatepickerRovingTabindex(dpDiv) { 656 const $datepicker = $(dpDiv); 657 const $dateCells = $datepicker.find('td:not(.ui-datepicker-unselectable) a.ui-state-default'); 658 if (!$dateCells.length) { return; } 659 // Leave an intact roving position alone — a timepicker slider stop is not a redraw. 660 if ($dateCells.filter('[tabindex="0"]').length === 1) { return; } 661 $dateCells.attr('tabindex', '-1').removeClass('ui-state-focus ui-state-hover'); 662 $datepicker.find('.ui-datepicker-prev, .ui-datepicker-next').attr('tabindex', '0'); 663 const $currentDay = $datepicker.find('.ui-datepicker-current-day a'); 664 const $today = datepickerTodayCell($datepicker); 665 ($currentDay.length ? $currentDay : ($today.length ? $today : $dateCells.first())) 666 .attr('tabindex', '0').addClass('ui-state-focus'); 667} 668 669// An empty field emits no current-day cell: _generateHTML compares against new Date(9999, 9, 9). 670function datepickerTodayCell(dpDiv) { 671 return $(dpDiv).find('td.ui-datepicker-today:not(.ui-datepicker-unselectable) a.ui-state-default'); 672} 673 674// Restores the pattern after any redraw — _doKeyUp and Ctrl+arrow redraw without notifying. 675let datepickerRedrawObserver = null; 676function watchDatepickerRedraws(dpDiv, inputEl) { 677 if (datepickerRedrawObserver) { datepickerRedrawObserver.disconnect(); datepickerRedrawObserver = null; } 678 if (typeof MutationObserver === 'undefined' || !$(dpDiv).length) { return; } 679 datepickerRedrawObserver = new MutationObserver(function() { 680 if (!datepickerOpenFor(inputEl)) { return; } 681 applyDatepickerAria(dpDiv, datepickerAriaLabel(), inputEl); 682 restoreDatepickerRovingTabindex(dpDiv); 683 }); 684 datepickerRedrawObserver.observe($(dpDiv)[0], { childList: true }); 685} 686 687function seedDatepickerAnnouncement(dpDiv) { 688 datepickerAnnouncer().data('last', datepickerMonthLabel(dpDiv)); 689} 690 691function datepickerMonthChanged(inst) { 692 const keyboardNav = !!inst.dpDiv.data('keyboard-nav'); 693 inst.dpDiv.removeData('keyboard-nav'); 694 const label = datepickerAriaLabel(); 695 const inputEl = inst.input[0]; 696 setTimeout(function() { 697 if (!datepickerOpenFor(inputEl)) { return; } 698 applyDatepickerAria(inst.dpDiv, label, inputEl); 699 announceDatepickerMonth(datepickerMonthLabel(inst.dpDiv)); 700 }, 0); 701 applyDatepickerFocusManagement(inst.dpDiv, inputEl, keyboardNav); 702} 703 704function bindDatepickerOpenKeys(inputEl) { 705 // A disabled field can never open the picker, so it must not advertise one. 706 if (!inputEl || $(inputEl).is(':disabled')) { return; } 707 $(inputEl).on('keydown.datepicker-open', function(e) { 708 if (e.keyCode !== 40) { return; } 709 e.preventDefault(); 710 const openForThis = datepickerOpenFor(this); 711 if (openForThis) { 712 // Scoped to date cells: the addon's slider handles are also <span tabindex="0">. 713 const $target = $('#ui-datepicker-div').find('a.ui-state-default[tabindex="0"]').first(); 714 if ($target.length) { $target.focus(); } 715 } else { 716 $(this).data('datepicker-keyboard-open', true); 717 $(this).datepicker('show'); 718 } 719 }); 720 setDatepickerExpanded(inputEl, false); 721 datepickerAnnouncer(); 722} 723 724function applyDatepickerAria(dpDiv, label, inputEl) { 725 if (inputEl && !datepickerOpenFor(inputEl)) { 726 setDatepickerExpanded(inputEl, false); 727 return; 728 } 729 const $datepicker = $(dpDiv); 730 $datepicker.attr({'role': 'dialog', 'aria-label': label}); 731 if (inputEl) { setDatepickerExpanded(inputEl, true); } 732 733 const $calendar = $datepicker.find('.ui-datepicker-calendar'); 734 $calendar.attr({'role': 'grid', 'aria-label': datepickerMonthLabel(dpDiv)}); 735 $calendar.find('tr').attr('role', 'row'); 736 $calendar.find('td:not(.ui-datepicker-unselectable)').attr({'role': 'gridcell', 'aria-selected': 'false'}); 737 $calendar.find('td.ui-datepicker-unselectable').attr({'role': 'gridcell', 'aria-disabled': 'true'}); 738 $calendar.find('.ui-datepicker-current-day').attr('aria-selected', 'true'); 739 740 const $navButtons = $datepicker.find('.ui-datepicker-prev, .ui-datepicker-next'); 741 $navButtons.attr('role', 'button'); 742 $navButtons.filter('.ui-state-disabled').attr('aria-disabled', 'true'); 743 $navButtons.not('.ui-state-disabled').removeAttr('aria-disabled'); 744 745 if (inputEl) { bindDatepickerButtonPaneFocus(dpDiv, inputEl); } 746} 747 748// On the buttons, not delegated on the div: onClose offs the div's handlers mid-click. 749// Returns focus to the field without showOn:'focus' reopening the picker. No-op when focu
749s is 750// already there: .focus() fires no event then, so the flag would survive and swallow the next open. 751function returnFocusToDatepickerField(inputEl) { 752 if (document.activeElement === inputEl) { return; } 753 $(inputEl).data('datepicker-suppress-open', true); 754 $(inputEl).focus(); 755} 756 757function bindDatepickerButtonPaneFocus(dpDiv, inputEl) { 758 const $datepicker = $(dpDiv); 759 const $input = $(inputEl); 760 $datepicker.find('.ui-datepicker-buttonpane button') 761 .off('click.datepicker-accessibility') 762 .on('click.datepicker-accessibility', function() { 763 if ($(this).hasClass('ui-datepicker-close')) { 764 setTimeout(function() { returnFocusToDatepickerField(inputEl); }, 10); 765 return; 766 } 767 setTimeout(function() { 768 if (!datepickerOpenFor(inputEl)) { return; } 769 const $target = $datepicker.find('a.ui-state-default[tabindex="0"]').first(); 770 if ($target.length) { $target.focus(); } 771 }, 0); 772 }); 773 774 // Mouse selection too: _selectDate hides the picker and its own restore is dead code. Also 775 // reached by keyboard selection, which triggers a click on the cell. 776 $datepicker.find('td[data-handler="selectDay"] a') 777 .off('click.datepicker-accessibility') 778 .on('click.datepicker-accessibility', function() { 779 setTimeout(function() { 780 // pick_date_time stays open for the time controls, so only restore when it closed. 781 if (datepickerOpenFor(inputEl)) { return; } 782 returnFocusToDatepickerField(inputEl); 783 }, 10); 784 }); 785} 786 787function datepickerCellForDate(dpDiv, date) { 788 const $cells = $(dpDiv).find('td[data-month="' + date.getMonth() + '"][data-year="' + date.getFullYear() + '"]') 789 .not('.ui-datepicker-unselectable').find('a.ui-state-default'); 790 return $cells.filter(function() { return parseInt($(this).text(), 10) === date.getDate(); }).first(); 791} 792 793function datepickerDateOfCell($cell) { 794 const $td = $cell.closest('td'); 795 const year = parseInt($td.attr('data-year'), 10);
796 const month = parseInt($td.attr('data-month'), 10); 797 const day = parseInt($cell.text(), 10); 798 if (isNaN(year) || isNaN(month) || isNaN(day)) { return null; } 799 return new Date(year, month, day); 800} 801 802function applyDatepickerFocusManagement(dpDiv, inputEl, moveFocus) { 803 setTimeout(function() { 804 if (inputEl && !datepickerOpenFor(inputEl)) { return; } 805 const $datepicker = $(dpDiv); 806 const $input = $(inputEl); 807 $datepicker.off('keydown.datepicker-accessibility'); 808 const $dateCells = $datepicker.find('td:not(.ui-datepicker-unselectable) a.ui-state-default'); 809 810 const focusDateStamp = $datepicker.data('focus-date'); 811 const focusNav = $datepicker.data('focus-nav'); 812 $datepicker.removeData('focus-date').removeData('focus-nav'); 813 814 if ($dateCells.length) { 815 $dateCells.attr('tabindex', '-1').removeClass('ui-state-focus ui-state-hover'); 816 $datepicker.find('.ui-datepicker-prev, .ui-datepicker-next').attr('tabindex', '0'); 817 818 let $focusTarget = focusDateStamp ? datepickerCellForDate($datepicker, new Date(focusDateStamp)) : null; 819 if (!$focusTarget || !$focusTarget.length) { 820 const $currentDay = $datepicker.find('.ui-datepicker-current-day a'); 821 const $today = datepickerTodayCell($datepicker); 822 // Must match restoreDatepickerRovingTabindex's chain, or two cells get highlighted. 823 $focusTarget = $currentDay.length ? $currentDay : ($today.length ? $today : $dateCells.first()); 824 } 825 $focusTarget.attr('tabindex', '0').addClass('ui-state-focus'); 826 827 const $navToRefocus = focusNav ? $datepicker.find('.ui-datepicker-' + focusNav) : $(); 828 if ($navToRefocus.length && $navToRefocus.attr('data-handler')) { 829 $navToRefocus.focus(); 830 } else if (moveFocus !== false) { 831 $focusTarget.focus(); 832 } 833 } 834 835 const moveFocusByDays = function($from, delta) { 836 const fromDate = datepickerDateOfCell($from); 837 if (!fromDate) { return null; } 838 const target = new Date(fromDate.getFullYear(), fromDate.getMonth(), fromDate.getDate() + delta); 839 const $inView = datepickerCellForDate($datepicker, target); 840 if ($inView.length) { return $inView; } 841 const $nav = $datepicker.find(delta < 0 ? '.ui-datepicker-prev' : '.ui-datepicker-next'); 842 // Disabled arrows render without [data-handler], so the click is a no-op: set no flag. 843 if (!$nav.attr('data-handler')) { return null; } 844 $datepicker.data('focus-date', target.getTime()); 845 $datepicker.data('keyboard-nav', true); 846 $nav.trigger('click'); 847 return null; 848 }; 849 const stepMonths = function($from, offset) { 850 const fromDate = datepickerDateOfCell($from); 851 if (fromDate) { 852 const firstOfTarget = new Date(fromDate.getFullYear(), fromDate.getMonth() + offset, 1); 853 const daysInTarget = new Date(firstOfTarget.getFullYear(), firstOfTarget.getMonth() + 1, 0).getDate(); 854 const day = Math.min(fromDate.getDate(), daysInTarget); 855 $datepicker.data('focus-date', new Date(firstOfTarget.getFullYear(), firstOfTarget.getMonth(), day).getTime()); 856 } 857 $datepicker.data('keyboard-nav', true); 858 $.datepicker._adjustDate($input[0], offset, 'M'); 859 }; 860 861 $datepicker.on('keydown.datepicker-accessibility', function(e) { 862 const $allDates = $datepicker.find('td:not(.ui-datepicker-unselectable) a.ui-state-default'); 863 const $active = $allDates.filter('[tabindex="0"]'); 864 const onDateCell = $(e.target).is('a.ui-state-default'); 865 const onNavButton = $(e.target).is('.ui-datepicker-prev, .ui-datepicker-next'); 866 let $next = null; 867 868 if (onDateCell && (e.keyCode === 37 || e.keyCode === 39 || e.keyCode === 38 || e.keyCode === 40)) { 869 e.preventDefault(); 870 const delta = { 37: -1, 39: 1, 38: -7, 40: 7 }[e.keyCode]; 871 $next = moveFocusByDays($active, delta); 872 } else if (onNavButton && (e.keyCode === 13 || e.keyCode === 32)) { // Enter/Space on ◀/▶ 873 e.preventDefault(); 874 const $nav = $(e.target); 875 if ($nav.attr('data-handler')) { 876 $datepicker.data('focus-nav', $nav.hasClass('ui-datepicker-prev') ? 'prev' : 'next'); 877 $datepicker.data('keyboard-nav', true); 878 $nav.trigger('click'); 879 } 880 } else if (onDateCell && (e.keyCode === 36 || e.keyCode === 35)) { // Home/End — first/last day of week 881 e.preventDefault(); 882 const $rowDates = $(e.target).closest('tr').find('td:not(.ui-datepicker-unselectable) a.ui-state-default'); 883 $next = (e.keyCode === 36) ? $rowDates.first() : $rowDates.last(
883); 884 } else if (onDateCell && (e.keyCode === 33 || e.keyCode === 34)) { // PageUp/PageDown — month, +Shift year 885 e.preventDefault(); 886 stepMonths($active, (e.keyCode === 33 ? -1 : 1) * (e.shiftKey ? 12 : 1)); 887 } else if (onDateCell && (e.keyCode === 32 || e.keyCode === 13)) { // Space/Enter — select 888 e.preventDefault(); 889 $active.trigger('click'); 890 setTimeout(function() { 891 if ($.datepicker._datepickerShowing) { 892 $datepicker.find('a.ui-state-default[tabindex="0"]').first().focus(); 893 } else { 894 returnFocusToDatepickerField(inputEl); 895 } 896 }, 10); 897 } else if (e.keyCode === 27) { // Escape — close, return focus, suppress reopen 898 e.preventDefault(); 899 e.stopPropagation(); 900 ($input.datepicker ? $input.datepicker('hide') : $datepicker.hide()); 901 setTimeout(() => returnFocusToDatepickerField(inputEl), 10); 902 } else if (e.keyCode === 9) { // Tab boundary — close and advance past the input 903 const $focusable = $datepicker.find( 904 '[tabindex="0"], input:not([disabled]):not([tabindex="-1"]), ' + 905 'select:not([disabled]):not([tabindex="-1"]), button:not([disabled]):not([tabindex="-1"])' 906 ).filter(':visible'); 907 const idx = $focusable.index(e.target); 908 if ((e.shiftKey && idx === 0) || (!e.shiftKey && idx === $focusable.length - 1)) { 909 const isShift = e.shiftKey; 910 e.preventDefault(); 911 e.stopPropagation(); 912 ($input.datepicker ? $input.datepicker('hide') : $datepicker.hide()); 913 // PAST the input, not back to it: focusing it would reopen via showOn:focus. 914 setTimeout(function() { 915 const scope = $input.closest('.modal, #facebox, .facebox, [role="dialog"]'); 916 // Exclude the closing picker: mid-fade, still :visible, and at body level. 917 const $closing = $('#ui-datepicker-div'); 918 const tabbable = (scope.length ? scope : $(document)).find( 919 'a[href]:not([tabindex="-1"]), ' + 920 'input:not([disabled]):not([tabindex="-1"]), ' + 921 'select:not([disabled]):not([tabindex="-1"]), ' + 922 'textarea:not([disabled]):not([tabindex="-1"]), ' + 923 'button:not([disabled]):not([tabindex="-1"]), ' + 924 '[tabindex]:not([tabindex="-1"])' 925 ).not($closing).not($closing.find('*')).filter(':visible').toArray(); 926 if (isShift) { 927 returnFocusToDatepickerField(inputEl); 928 return; 929 } 930 const inputIdx = tabbable.indexOf($input[0]); 931 const target = inputIdx === -1 ? null : tabbable[inputIdx + 1]; 932 if (target) { $(target).focus(); } else { returnFocusToDatepickerField(inputEl); } 933 }, 10); 934 } 935 } 936 937 if ($next && $next.length) { 938 $active.attr('tabindex', '-1').removeClass('ui-state-focus'); 939 $next.attr('tabindex', '0').addClass('ui-state-focus').focus(); 940 } 941 }); 942 }, 0); 943} 944 945function setDatepickerPos(input, inst) { 946 if ($(input).data('datepicker-suppress-open')) { 947 $(input).removeData('datepicker-suppress-open'); 948 return false; 949 } 950 const keyboardOpen = !!$(input).data('datepicker-keyboard-open'); 951 $(input).removeData('datepicker-keyboard-open'); 952 const rect = input.getBoundingClientRect(); 953 setTimeout(function () { 954 const scrollTop = inst.dpDiv.css('position') === 'fixed' ? 0 : $(window).scrollTop(); 955 inst.dpDiv.css({ top: rect.top + input.offsetHeight + scrollTop }); 956 957 applyDatepickerAria(inst.dpDiv, datepickerAriaLabel(), input); 958 seedDatepickerAnnouncement(inst.dpDiv); 959 watchDatepickerRedraws(inst.dpDiv, input); 960 applyDatepickerFocusManagement(inst.dpDiv, input, keyboardOpen); 961 }, 0); 962} 963 964function save_date_picker(date, picker, name, callback) {
965 var input = $('#' + name); 966 setDatepickerExpanded(input, false); 967 releaseSharedDatepickerState(); 968 var altField = $('#' + name + '_alt'); 969 var altValue = altField.val(); 970 var year = '', month = '', day = ''; 971 972 if(altValue && altValue.trim() !== ''){ 973 // Parse from stable ISO format (YYYY-MM-DD) 974 var parts = altValue.split('-'); 975 if(parts.length === 3){ 976 var y = parseInt(parts[0], 10); 977 var m = parseInt(parts[1], 10); 978 var d = parseInt(parts[2], 10); 979 if (!isNaN(y) && !isNaN(m) && !isNaN(d)) { 980 year = y; 981 month = m; 982 day = d; 983 } else { 984 year = ''; 985 month = ''; 986 day = ''; 987 } 988 } 989 } 990 991 $('#' + name + '_year').val(year); 992 $('#' + name + '_month').val(month); 993 $('#' + name + '_day').val(day); 994 995 if(callback){ 996 callback(year, month, day) 997 } 998} 999 1000// date time picker 1001 1002function save_date_time_picker(date, picker, name, use_24) { 1003 setDatepickerExpanded($('#' + name), false); 1004 releaseSharedDatepickerState(); 1005 var input = $('#' + name).val().trim(); 1006 var altField = $('#' + name + '_alt'); 1007 var altValue = altField.val(); 1008 1009 if (input == '' || !altValue || altValue.trim() === '') { 1010 $('#' + name + '_year').val(''); 1011 $('#' + name + '_month').val(''); 1012 $('#' + name + '_day').val(''); 1013 $('#' + name + '_hours').val(''); 1014 $('#' + name + '_minutes').val(''); 1015 } else { 1016 // Parse from stable ISO format (YYYY-MM-DD HH:MM:SS) 1017 var parts = altValue.split(' '); 1018 if(parts.length === 2){ 1019 var dateParts = parts[0].split('-'); 1020 var timeParts = parts[1].split(':'); 1021 1022 if(dateParts.length === 3 && timeParts.length >= 2){ 1023 var year = parseInt(dateParts[0], 10); 1024 var month = parseInt(dateParts[1], 10); 1025 var day = parseInt(dateParts[2], 10); 1026 var hours = parseInt(timeParts[0], 10); 1027 var minutes = parseInt(timeParts[1], 10); 1028 if (!isNaN(year) && !isNaN(month) && !isNaN(day) && !isNaN(hours) && !isNaN(minutes)) { 1029 $('#' + name + '_year').val(year); 1030 $('#' + name + '_month').val(month); 1031 $('#' + name + '_day').val(day); 1032 $('#' + name + '_hours').val(hours); 1033 $('#' + name + '_minutes').val(minutes); 1034 } else { 1035 $('#' + name + '_year').val(''); 1036 $('#' + name + '_month').val(''); 1037 $('#' + name + '_day').val(''); 1038 $('#' + name + '_hours').val(''); 1039 $('#' + name + '_minutes').val(''); 1040 } 1041 } 1042 } 1043 } 1044} 1045 1046// set_self_registration 1047 1048function set_self_registration(value) { 1049 if (value == 'WithAccessCode') { 1050 $('#configure_access_codes').show(); 1051 } else { 1052 $('#configure_access_codes').hide(); 1053 } 1054 1055 ajax_request('/registration_codes/set_type?value=' + value); 1056} 1057 1058function text_field_for_organization(checkbox) { 1059 if (checkbox.checked) { 1060 hide_element('default_org_option'); 1061 } else { 1062 show_element('default_org_option'); 1063 } 1064 1065 ajax_request('/account_fields/set_text_field_for_organization?value=' + check_s(checkbox)); 1066} 1067 1068function start_with_default_org_in_dropdown(checkbox) { 1069 ajax_request('/account_fields/set_start_with_default_org_in_dropdown?value=' + check_s(checkbox)); 1070} 1071 1072function org_dropdown_other_option(checkbox) { 1073 ajax_request('/account_fields/set_org_dropdown_other_option?value=' + check_s(checkbox)); 1074} 1075 1076// custom dropdown on signup 1077 1078function toggle_custom_organization_input_view(value){ 1079 if (value === 'other') { 1080 $('.custom_organization_input').show(); 1081 } else { 1082 $('.custom_organization_input').hide(); 1083 } 1084} 1085 1086// view as 1087 1088function view_as_student(class_id) { 1089 $.facebox({ 1090 'ajax' : '/teacher_class/view_as_student/' + class_id + '?from=' + encodeURIComponent(window.location.pathname + window.location.search) 1091 }); 1092} 1093 1094function view_as_teacher(class_id) { 1095 window.location.href = '/student_class/view_as_teacher/' + class_id + '?from=' + encodeURIComponent(window.location.pathname + window.location.search); 1096} 1097 1098// canned messages 1099 1100function set_default_message(action_id, dropdown) { 1101 if (dropdown.value == 0) { 1102 $.facebox({ 1103 'ajax' : '/canned_messages_admin/add_message/' + action_id 1104 }); 1105 } else { 1106 ajax_request('/canned_messages_admin/set_default_message/' + action_id + '?value=' + dropdown.value); 1107 } 1108} 1109 1110/* 1111 * what happens when you click "Save"? 1112 */ 1113 1114function select_message(action_id, dropdown) { 1115 if (dropdown.value == 0) { 1116 $.facebox({ 1117 'ajax' : '/canned_messages_admin/add_message/' + action_id 1118 }); 1119 } else { 1120 $.ajax({ 1121 url : '/add_accounts_using_form/set_message?message_id=' + dropdown.value, 1122 async : false, 1123 success : function(data) { 1124 $('#message_subject').html('<p>' + data.subject + '</p>'); 1125 $('#message_content').html(data.content); 1126 } 1127 }); 1128 } 1129} 1130 1131// time zone 1132 1133function check_time_zone(time) { 1134 var browser_time = new Date(); 1135 var server_time = new Date(time.year, time.month - 1, time.day, time.hour, time.min); 1136 var diff_time = Math.abs(browser_time.getTime() - server_time.getTime()); 1137 1138 // 15 minutes is 900000 milliseconds 1139 if (diff_time > 900000) { 1140 show_element('time_warning'); 1141 } 1142} 1143 1144// time 1145 1146function write_time() { 1147 if ($('input#time').length == 0) { 1148 var now = new Date(); 1149 var time = now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate() + ' ' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds(); 1150 $('.signupForm, .formAutoWidths, #signup_form').prepend("<input type='hidden' id='time' name='time' value='" + time + "' />"); 1151 } 1152} 1153 1154// dark mode toggle 1155 1156function dark_mode_toggle() { 1157 if (document.documentElement.getAttribute('data-theme') == "dark") { 1158 document.documentElement.setAttribute('data-theme', ''); 1159 $(".tox-tinymce iframe").contents().find("body").removeClass('dark_editor'); 1160 } else { 1161 document.documentElement.setAttribute('data-theme', 'dark'); 1162 $(".tox-tinymce iframe").contents().find("body").addClass('dark_editor'); 1163 } 1164 1165 if ($('.grade_book').length > 0) { 1166 gradebook_colors(); 1167 draw_gradebook(); 1168 } 1169 1170 $.post('/account/set_dark_mode', function(){ 1171 if( $('body rapi-doc').length > 0 ) 1172 location.reload(); 1173 }); 1174} 1175 1176// configure notifications 1177 1178function set_email_notification(attribute, checkbox) { 1179 ajax_request('/notifications/set_email_notification?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 1180} 1181 1182function set_mobile_notification(attribute, checkbox) { 1183 ajax_request('/notifications/set_mobile_notification?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 1184} 1185 1186// full admins 1187 1188function set_full_admin(checkbox, administrator_id) { 1189 ajax_request('/administrators/set_full_admin?administrator_id=' + administrator_id + '&value=' + (checkbox.checked ? 'true' : 'false')); 1190} 1191 1192// billing contacts 1193
1194function billing_contact(checkbox, administrator_id) { 1195 ajax_request('/administrators/set_billing_contact?administrator_id=' + administrator_id + '&value=' + (checkbox.checked ? 'true' : 'false')); 1196} 1197 1198// contact messages 1199 1200function contact_messages(checkbox, administrator_id) { 1201 ajax_request('/administrators/set_contact_messages?administrator_id=' + administrator_id + '&value=' + (checkbox.checked ? 'true' : 'false')); 1202} 1203 1204// e-commerce access 1205 1206function ecommerce_access(checkbox, administrator_id) { 1207 ajax_request('/administrators/set_ecommerce_access?administrator_id=' + administrator_id + '&value=' + (checkbox.checked ? 'true' : 'false')); 1208} 1209 1210// resources 1211 1212function update_resources(controller, id, lesson, section, folder, popup) { 1213 var subject = $('#resource_subject'); 1214 var type = $('#resource_type'); 1215 var library = $('#resource_library'); 1216 var url = '/' + controller + '/new_from_favorites/' + id + '?'; 1217 var args = []; 1218 var name = $('#resource_name').val(); 1219 1220 if (name) { 1221 args.push('resource_name=' + name); 1222 } 1223 1224 if (lesson){ 1225 args.push('lesson_id=' + lesson); 1226 } 1227 1228 if (section){ 1229 args.push('section_id=' + section); 1230 } 1231 1232 if (folder){ 1233 args.push('folder=' + folder); 1234 } 1235 1236 if (subject){ 1237 args.push('subject=' + subject.val()); 1238 } 1239 1240 if (type){ 1241 args.push('type=' + type.val()); 1242 } 1243 1244 if (library){ 1245 args.push('library=' + library.val()); 1246 } 1247 1248 url += args.join('&'); 1249 1250 if (popup) { 1251 $.facebox({ 1252 'ajax' : url 1253 }); 1254 } else { 1255 window.location.href = url; 1256 } 1257} 1258 1259// click to chat 1260 1261function playChatSound() { 1262 soundManager.play('user_sound'); 1263} 1264 1265function display_chat_alert(from_id, from_name, chat_room_id) { 1266 if (chat_alert_displayed) { 1267 return; 1268 } 1269 1270 chat_alert_displayed = true; 1271 var alerts = $('#alerts'); 1272 from_name = from_name.replace('"', '\"'); 1273 1274 if (is_mobile_app_mode()) { 1275 alerts.html('<div class="alert_block info keepopen" role="alert"><div class="alert_flex"><div class="alert_icon"><i class="info inverted"></i></div><p>' + chat_request_text + ' ' + from_name + ': <a href="javascript:accept_chat_request_app(' + chat_room_id + ');">' + accept_text + '</a> | <a href="javascript:ignore_chat_request(' + chat_room_id + ');">' + ignore_text + '</a></p></div></div>'); 1276 1277 } else { 1278 alerts.html('<div class="alert_block info keepopen" role="alert"><div class="alert_flex"><div class="alert_icon"><i class="info inverted"></i></div><p>' + chat_request_text + ' ' + from_name + ': <a href="javascript:accept_chat_request(' + chat_room_id + ');">' + accept_text + '</a> | <a href="javascript:ignore_chat_request(' + chat_room_id + ');">' + ignore_text + '</a></p></div></div>'); 1279 } 1280 1281 alerts.show(); 1282 1283 if (loaded_sound_manager) { 1284 playChatSound(); 1285 } else { 1286 $.getScript('/javascripts/soundmanager2-jsmin.js', function() { 1287 init_sound_manager(playChatSound); 1288 }); 1289 } 1290} 1291 1292function hide_chat_alert() { 1293 var alerts = $('#alerts'); 1294 alerts.html(''); 1295 alerts.hide(); 1296 chat_alert_displayed = false; 1297} 1298 1299function click_to_chat(user_id) { 1300 $.ajax({ 1301 type: 'POST', 1302 url : '/click_to_chat/start_chat?user_id=' + user_id, 1303 success : function(json, text_status, jqXHR) { 1304 launch_chat('/click_to_chat/launch?chat_room_id=' + json.chat_room_id + '&chat_room_name=' + encodeURIComponent(json.user_name.replace(/'/g, "%27")) + '&invited_user_id=' + user_id); 1305 }, 1306 error : function(jqXHR, text_status, errorThrown) { 1307 $.alert({content: 'error ' + text_status}); 1308 } 1309 }); 1310} 1311 1312function accept_chat_request(chat_room_id) { 1313 $.ajax({ 1314 type: 'POST', 1315 url : '/click_to_chat/join_chat?chat_room_id=' + chat_room_id, 1316 success : function(json, text_status, jqXHR) { 1317 if (json.status) { 1318 hide_chat_alert(); 1319 launch_chat('/click_to_chat/launch?chat_room_id=' + chat_room_id + '&chat_room_name=' + encodeURIComponent(json.user_name.replace(/'/g, "%27"))); 1320 } else { 1321 $('#alerts .info p').html(chat_request_canceled_text); 1322 setTimeout(hide_chat_alert, 5000); 1323 } 1324 }, 1325 error : function(jqXHR, text_status, errorThrown) { 1326 $.alert({content: 'error ' + text_status}); 1327 } 1328 }); 1329} 1330 1331function ignore_chat_request(chat_room_id) { 1332 hide_chat_alert(); 1333 ajax_request('/click_to_chat/ignore?chat_room_id=' + chat_room_id); 1334} 1335 1336// chat 1337 1338function start_chat(chat_url, redirect_url) { 1339 if (is_mobile_app_mode()) { 1340 start_chat_app(chat_url, redirect_url); 1341 } else { 1342 launch_chat(chat_url); 1343 } 1344} 1345 1346function launch_chat(url) { 1347 var chatroom_id = create_chat(url); 1348 1349 $(window).on('click', function(event) { 1350 if (event.target.href) { 1351 $(window).off('unload beforeunload'); 1352 } 1353 }); 1354 1355 $(window).on('unload beforeunload', function(event) { 1356 ajax_request('/chat_room/leaving/' + chatroom_id); 1357 }); 1358} 1359 1360function relaunch_chat(url) { 1361 launch_chat(url + '&event=relaunched'); 1362} 1363 1364function create_chat(url) { 1365 var args = get_args(url); 1366 var chatroom_id = args['chat_room_id']; // should always be present 1367 var chatroom_name = (args['chat_room_name'] ? decodeURIComponent(args['chat_room_name']) : 'Chat'); 1368 var invited_user_id = (args['invited_user_id'] || 'null'); 1369 1370 var popout_link = '<a href="javascript:void(0)" onclick="pop_out_chat(\'' + url + '\')" class="popout"><i class="popout inverted"></i><span class="textOffScreen">Popout window</span></a>'; 1371 var chatContainer = '<div id="chatContainer" chatroom_id="' + chatroom_id + '"><div class="header"><h4>' + chatroom_name.replace(/\+/g, " ").replace(/%27/g, "'") + '</h4>' + popout_link + '<a href="javascript:void(0)" onclick="close_chat(' + chatroom_id + ', ' + invited_user_id + ')" class="close"><i class="xCross inverted"></i><span class="textOffScreen">Close chat</span></a></div><div id="chatIframe"><iframe src="' + url + '"></iframe></div></div>'; 1372 1373 if ($('#chatContainer').length > 0) { 1374 // different chat room already embedded 1375 window.open(url+'&event=popped_out&disable_popin=true', '_blank', 'height=611px,width=500px,toolbar=yes,directories=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,modal=no'); 1376 } else { 1377 // embed chat room in frame 1378 $('#contentWrap').append(chatContainer); 1379 } 1380 1381 return chatroom_id; 1382} 1383 1384function pop_out_chat(url) { 1385 url = (url.indexOf('?') > -1 ? url + '&event=popped_out' : url + '?event=popped_out'); 1386 var childWindow = window.open(url, '_blank', 'height=611px,width=500px,toolbar=yes,directories=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,modal=no'); 1387 $('#chatContainer').remove(); 1388} 1389 1390function pop_in_close() { 1391 // http://stackoverflow.com/questions/4458630/unable-to-unbind-the-window-beforeunload-event-in-jquery 1392 window.onbeforeunload = null; // suppress default call to close_chat() 1393 window.opener.launch_chat(window.location.href.replace('event=popped_out', 'event=popped_in')); 1394 window.close(); 1395} 1396 1397function close_chat(chat_room_id, invited_user_id, multi) { 1398 $('#chatContainer').remove(); 1399 1400 if (invited_user_id == null) { 1401 ajax_request('/chat_room/leaving/' + chat_room_id + (multi == null ? '' : '?multi=true'), { 1402 asynchronous : false 1403 }); 1404 } else { 1405 ajax_request('/chat_room/leaving/' + chat_room_id + '?invited_user_id=' + invited_user_id + (multi == null ? '' : '&multi=true'), { 1406 asynchronous : false 1407 }); 1408 } 1409} 1410 1411// user popups 1412 1413function over_user() { 1414 if (user_timer == null) { 1415 // pop up after one second 1416 user_href = $(this); 1417 user_timer = setTimeout(popup_user, 1000); 1418 } 1419} 1420 1421function clear_user_timer() { 1422 if (user_timer) { 1423 clearTimeout(user_timer); 1424 user_timer = null; 1425 } 1426} 1427 1428function popup_user() { 1429 if (user_href.attr('rel')) { 1430 return; 1431 } 1432 1433 // mark and cache 1434 user_href.attr('rel', 'popup'); 1435 1436 // exiting title interferes with tooltip 1437 user_href.removeAttr('title'); 1438 1439 // get user id 1440 var href = user_href.attr('href'); 1441 var parts = href.split("/"); 1442 var user_id = parts[3]; 1443 var url = '/popup/user/' + user_id; 1444 1445 // fetch tooltip HTML 1446 var html; 1447 1448 $.ajax({ 1449 url : url, 1450 async : false, // make this async? 1451 success : function(data) { 1452 html = data; 1453 } 1454 }); 1455 1456 // attach tooltip 1457 var tool_tip = $(html); 1458 1459 // add after element 1460 user_href.after(tool_tip); 1461 1462 // can't use delay because it triggers AJAX before delay, not after 1463 user_href.tooltip({ 1464 events : { 1465 def : 'mouseenter,mouseleave' 1466 }, 1467 relative : true, 1468 position : user_href.offset().top < 200 || user_href.parents('.profileTable').length ? "bottom left" : "top left", 1469 effect : 'slide', 1470 delay: 1000 // one second 1471 }); 1472 1473 if(user_href.offset().top < 200 || user_href.parents('.profileTable').length){ 1474 user_href.siblings('.tooltip').addClass('tooltipBot'); 1475 } 1476 1477 // attach facebox hook 1478 //tool_tip.find('a[rel*=facebox]').facebox(); 1479 tool_tip.find('a[rel*=facebox]').each( function() { 1480 if(!$(this).hasClass("_processed")) { 1481 $(this).addClass("_processed").facebox(); 1482 } 1483 }); 1484 1485 if ($.browser.mozilla) { 1486 var triggerCount = 0; 1487 1488 user_href.mouseenter(function() { 1489 triggerCount++; 1490 1491 if (triggerCount == 1) { 1492 user_href.trigger('mouseenter'); 1493 } else { 1494 triggerCount = 0; 1495 } 1496 }); 1497 1498 user_href.mouseleave(function() { 1499 triggerCount++; 1500 1501 if (triggerCount == 1) { 1502 user_href.trigger('mouseleave'); 1503 } else { 1504 triggerCount = 0; 1505 } 1506 }); 1507 } 1508 1509 // need to retrigger event to show tooltip; tried tooltip.show() but this didn't work 1510 user_href.trigger('mouseenter'); 1511} 1512 1513function out_user() { 1514 clear_user_timer(); 1515} 1516 1517function send_popup_message(user_id) { 1518 var subject = get_value('subject'); 1519 var content = get_value('content'); 1520 1521 $.ajax({ 1522 type : 'POST', 1523 url : '/popup/submit_message/' + user_id + '?subject=' + encodeURIComponent(subject) + '&content=' + encodeURIComponent(content), 1524 success : function(data) { 1525 $.facebox(data); 1526 } 1527 }); 1528} 1529 1530function disable_user_popups() { 1531 disable_user_popups_flag = true; 1532} 1533 1534function disable_user_popups_in(container) { 1535 var user_hrefs = $(container + ' a[href^="/user/show/"]'); 1536 user_hrefs.off('mouseover'); 1537 user_hrefs.off('mouseout'); 1538} 1539 1540function enable_user_popups() { 1541 if (disable_user_popups_flag) { 1542 return; 1543 } 1544 1545 var user_hrefs = $('a[href^="/user/show/"]'); 1546 1547 user_hrefs.on('mouseover', over_user); 1548 user_hrefs.on('mouseout', out_user); 1549} 1550 1551// pop-ups 1552 1553function popup_clicked(element) { 1554 let url = $(element).attr('href'); 1555 if (window.tinyMCE) url += (url.split('?')[1] ? '&' : '?') + 'editor_js_loaded=true'; 1556
1557 // Store the trigger element and its href so focus can be restored when the popup closes. 1558 // The href is used as a selector to re-find the element after page_router AJAX navigation 1559 // replaces the DOM (e.g. after saving a to-do item). 1560 $._facebox_trigger = element; 1561 $._facebox_trigger_href = $(element).attr('href'); 1562 1563 $.facebox({ 1564 'ajax' : url 1565 }); 1566 1567 return false; 1568} 1569 1570// Restore focus to the element that triggered the popup after it closes 1571$(document).on('afterClose.facebox', function() { 1572 var trigger = $._facebox_trigger; 1573 var href = $._facebox_trigger_href; 1574 $._facebox_trigger = null; 1575 $._facebox_trigger_href = null; 1576 1577 if (trigger) { 1578 // If the original element is still in the DOM, focus it directly 1579 if ($.contains(document, trigger)) { 1580 $(trigger).focus(); 1581 } else if (href) { 1582 // Element was removed (e.g. page_router replaced the DOM after save). 1583 // Re-find it by href after the new content loads. 1584 $(window).one('loadcomplete', function() { 1585 var newTrigger = $('a[href="' + href + '"][aria-haspopup="true"]'); 1586 if (newTrigger.length) { 1587 newTrigger.first().focus(); 1588 } 1589 }); 1590 } 1591 } 1592}); 1593 1594function send_message_popup(element, form_id) { 1595 var selected_users = $('#' + form_id).find("input[name*='select[]']:checked"); 1596 var select_all = $('#' + form_id).find("input[name*='select_all']"); 1597 var user_ids = ''; 1598 var filter = $('form input[name=filter]'); 1599 1600 if (selected_users.length > 0 || select_all.length > 0) { 1601 if (select_all.length > 0) { 1602 user_ids += '&select_all=true'; 1603 1604 if (filter.length > 0) { 1605 user_ids += '&filter=' + encodeURIComponent(filter.last().val()); 1606 } 1607 } else { 1608 for (var i = 0; i < selected_users.length; i++) { 1609 user_ids += '&select[]=' + $(selected_users[i]).val(); 1610 } 1611 } 1612 $.ajax({ 1613 type: 'POST', 1614 url: $(element).attr('href'), 1615 data: user_ids, 1616 success: function(response) { 1617 $.facebox(response); 1618 }, 1619 error: function(response) { 1620 $.alert({ content: response.responseText }); 1621 } 1622 }); 1623 1624 } else { 1625 $.alert({content: "No items were selected."}); 1626 } 1627 1628 return false; 1629} 1630 1631function open_merge_popup(element, form_id) { 1632 var selected_users = $('#' + form_id).find("input[name*='select[]']:checked"); 1633 var select_all = $('#' + form_id).find("input[name*='select_all']"); 1634 var user_ids = ''; 1635 var filter = $('form input[name=filter]'); 1636 1637 if (selected_users.length > 0 || select_all.length > 0) { 1638 if (select_all.length > 0) { 1639 user_ids += '&select_all=true'; 1640 1641 if (filter.length > 0) { 1642 user_ids += '&filter=' + encodeURIComponent(filter.last().val()); 1643 } 1644 } else { 1645 for (var i = 0; i < selected_users.length; i++) { 1646 user_ids += '&select[]=' + $(selected_users[i]).val(); 1647 } 1648 } 1649 1650 $.ajax({ 1651 type: 'POST', 1652 url: $(element).attr('href'), 1653 data: user_ids, 1654 success: function(response) { 1655 $.facebox(response); 1656 }, 1657 error: function(response) { 1658 $.alert({ content: response.responseText }); 1659 } 1660 }); 1661 } else { 1662 $.alert({content: no_items_selected}); 1663 } 1664 1665 return false; 1666} 1667 1668// merge users popup: inline "add user" search + list management 1669 1670function merge_open_picker(btn) { 1671 merge_setup_picker_interceptor(); 1672 1673 window.__merge_detail_url = $(btn).data('detail-url'); 1674 window.__merge_picker_active = true; 1675 1676 // exclude users already in the merge list 1677 var url = $(btn).data('url'); 1678 var excluded = $('#merge_users_form input[name="select[]"]').map(function() { return this.value; }).get(); 1679 if (excluded.length) { 1680 url += (url.indexOf('?') === -1 ? '?' : '&') + 'excluded=' + encodeURIComponent(excluded.join(',')); 1681 } 1682 1683 // open the people picker stacked over the merge popup. 1684 $.facebox.open({ ajax: url }); 1685 1686 return false; 1687} 1688 1689// Intercept the people picker's "Select" button, but only while it was opened from 1690// the merge popup. Capture-phase + a flag so it beats the picker's own submit 1691// handler regardless of when filter.js loads, and so it never navigates the page. 1692function merge_setup_picker_interceptor() { 1693 if (window.__merge_picker_interceptor) { return; } 1694 window.__merge_picker_interceptor = true; 1695 1696 // Reset __merge_picker_active on every facebox close, not just the success path. 1697 if ($.facebox && $.facebox.close) { 1698 var __orig_facebox_close = $.facebox.close; 1699 $.facebox.close = function() { 1700 window.__merge_picker_active = false;
1701 return __orig_facebox_close.apply(this, arguments); 1702 }; 1703 } 1704 1705 document.addEventListener('click', function(e) { 1706 if (!window.__merge_picker_active) { return; } 1707 1708 var target = e.target; 1709 var btn = (target && target.closest) ? target.closest('button[type="submit"]') : null; 1710 var picker = document.getElementById('people_picker'); 1711 1712 if (!btn || !picker || !picker.contains(btn)) { return; } 1713 1714 e.preventDefault(); 1715 e.stopImmediatePropagation(); 1716 1717 var ids = ((typeof pp_obj !== 'undefined' && pp_obj.selected) || '').toString(); 1718 1719 if (!ids) { $.alert({ content: $('#merge_users_table').data('addEmpty') || 'Select at least one user to add.' }); return; } 1720 1721 // fetch the picked users' details, append their rows to the merge popup 1722 // (still in the DOM under the picker), then close the picker 1723 $.getJSON(window.__merge_detail_url, { user_ids: ids.split(',') }, function(data) { 1724 var picked = (data && data.results) || []; 1725 1726 for (var i = 0; i < picked.length; i++) { 1727 var u = picked[i]; 1728 merge_append_user_row({ 1729 id: u.id, 1730 text: ((u.first_name || '') + ' ' + (u.last_name || '')).trim(), 1731 userid: u.userid 1732 }); 1733 } 1734 1735 window.__merge_picker_active = false; 1736 $.facebox.close(); 1737 }).fail(function() { 1738 // leave the picker open and __merge_picker_active true so a retry Select is 1739 // still intercepted (not handed to the picker's own navigating submit) 1740 $.alert({ content: $('#merge_users_table').data('addFailed') || 'Could not add the selected user(s). Please try again.' }); 1741 }); 1742 }, true); 1743} 1744 1745function merge_append_user_row(user) { 1746 if (!user || !user.id) { return; } 1747 1748 // skip if the user is already in the list 1749 if ($('#merge_users_form input[name="select[]"][value="' + user.id + '"]').length > 0) { return; } 1750 1751 var $row = $('<tr class="merge_user_row"></tr>'); 1752 1753 var $keep = $('<td align="center"></td>'); 1754 $('<input type="radio" name="keep_id">') 1755 .attr('value', user.id) 1756 .attr('id', 'merge_keep_' + user.id) 1757 .attr('aria-label', ($('#merge_users_table').data('accountToKeep') || 'Account to keep') + ': ' + user.text) 1758 .appendTo($keep); 1759 // platform hides the native radio and renders the control via "+ label:before" 1760 $('<label></label>').attr('for', 'merge_keep_' + user.id).appendTo($keep); 1761 $('<input type="hidden" name="select[]">').attr('value', user.id).appendTo($keep); 1762 $row.append($keep); 1763 1764 $row.append($('<td></td>').text(user.text)); 1765 $row.append($('<td></td>').text(user.id)); 1766 $row.append($('<td></td>').text(user.userid || '')); 1767 1768 var $remove = $('<td align="center"></td>'); 1769 $('<a href="javascript:void(0);" class="merge_remove_user"><i class="delete"></i></a>') 1770 .attr('title', $('#merge_users_table').data('remove') || 'Remove') 1771 .attr('onclick', 'merge_remove_user(this); return false;') 1772 .appendTo($remove); 1773 $row.append($remove); 1774 1775 $('#merge_users_table tbody').append($row); 1776} 1777 1778function merge_remove_user(btn) { 1779 $(btn).closest('tr').remove(); 1780 1781 // if the removed row held the "keep" selection, default to the first remaining row 1782 if ($('#merge_users_form input[name="keep_id"]:checked').length === 0) { 1783 $('#merge_users_table tbody tr:first input[name="keep_id"]').prop('checked', true); 1784 } 1785 1786 return false; 1787} 1788 1789function merge_continue(btn) { 1790 var rows = $('#merge_users_table tbody tr'); 1791 1792 if (rows.length < 2) { 1793 $.alert({ content: $('#merge_users_table').data('minTwo') || 'Select at least two users to merge.' }); 1794 return false; 1795 } 1796 1797 if ($('#merge_users_form input[name="keep_id"]:checked').length === 0) { 1798 $.alert({ content: $('#merge_users_table').data('selectKeep') || 'Select the account to keep.' }); 1799 return false; 1800 } 1801 1802 $.confirm({ 1803 content: $(btn).data('mergeConfirm'), 1804 confirm: function() { 1805 // Submit the form to MembersController#submit_merge, which enqueues the 1806 // completion-merge job and redirects back to the list with a flash notice. 1807 document.getElementById('merge_users_form').submit(); 1808 } 1809 }); 1810 1811 return false; 1812} 1813 1814function popup_clicked_mobile_app(href) { 1815 $.facebox({ 1816 'ajax' : href 1817 }); 1818} 1819 1820function popup_form(name, html, preprocess) { 1821 // cleanup duplicate popup forms in the new UI - just keep the last one 1822 var forms = $('form[id="' + name + '"]'); 1823 if (forms.length > 1) { 1824 forms.each(function(index) { 1825 if (index < (forms.length - 1)) { 1826 $(this).parents('.popup').remove(); 1827 } 1828 }); 1829 } 1830 1831 tinyPop = true; 1832 if (html != null) {
1833 $('#' + name).submit(function() { 1834 var button = $(this).find('button'); 1835 button.attr('disabled', ''); 1836 tinyPop = false; 1837 $(this).ajaxSubmit({ 1838 beforeSerialize : function() { 1839 popup_form_before_serialize(html); 1840 }, 1841 success: function(data) { 1842 popup_form_ajax_success(data, preprocess) || button.prop('disabled', false); 1843 }, 1844 error: function(){ 1845 button.prop('disabled', false); 1846 } 1847 }); 1848 1849 return false; 1850 }); 1851 } else { 1852 $('#' + name).submit(function() { 1853 var button = $(this).find('button'); 1854 button.attr('disabled', ''); 1855 $(this).ajaxSubmit({ 1856 success: function(data) { 1857 popup_form_ajax_success(data, preprocess) || button.prop('disabled', false); 1858 }, 1859 error: function(){ 1860 button.prop('disabled', false); 1861 } 1862 }); 1863 1864 return false; 1865 }); 1866 } 1867} 1868 1869function popup_form_ajax_success(data, preprocess){ 1870 try { 1871 data = preprocess ? preprocess(data) : data; 1872 var json = jQuery.parseJSON(data); 1873 console.log("JSON", json); 1874 if (json.url.split('#')[0] == window.location.href.split('#')[0]) 1875 location.reload(); 1876 else{ 1877 1878 // we don't want any confirmations at that point 1879 if (typeof(tinymce) != 'undefined' && tinymce.activeEditor && $(document.body).hasClass('evo') && ($(document.body).find('.modal.is-open').find(tinymce.activeEditor.getElement()).length > 0)) 1880 tinymce.activeEditor.setDirty(false); 1881 1882 window.location.href = json.url; 1883 } 1884 1885 return true; 1886 1887 } catch (e) { 1888 if( data ) 1889 $.facebox(data); 1890 else 1891 $.facebox.close(); 1892 } 1893} 1894 1895function resources_popup_form(name) { 1896 $('#' + name).submit(function() { 1897 var button = $(this).find('button'); 1898 button.attr('disabled', ''); 1899 var errors = []; 1900 $('.tag-group-required').each(function(){ 1901 if($(this).val().length == 0){ errors.push($(this).attr('id')); } 1902 }); 1903 if(errors.length > 0){ 1904 $('#faceboxContent #alerts').html(tag_groups_error_string()).show(); 1905 $('#' + errors[0]).focus(); 1906 button.prop('disabled', false); 1907 }else{ 1908 var form = $(this); 1909 var copilot_check = form.find('#add_anchor'); 1910 copilot_check.removeAttr('disabled'); 1911 form.ajaxSubmit({ 1912 success: function(data) { 1913 if( copilot_check.length && copilot_check.is(':checked') ){ 1914 try { 1915 Excalibur.Ai.check_url(JSON.parse(data).url, true); 1916 $.facebox.close(); 1917 } 1918 catch (e) { 1919 if( data ) 1920 $.facebox(data); 1921 else 1922 $.facebox.close(); 1923 } 1924 } 1925 else 1926 popup_form_ajax_success(data) || button.prop('disabled', false); 1927 }, 1928 error: function(){ 1929 button.prop('disabled', false); 1930 } 1931 }); 1932 } 1933 1934 return false; 1935 }); 1936} 1937 1938function resources_html_popup_form(name, html, preprocess) { 1939 $('#' + name).submit(function() { 1940 var errors = []; 1941 $('.tag-group-required').each(function(){ 1942 if($(this).val().length == 0){ errors.push($(this).attr('id')); } 1943 }); 1944 if(errors.length > 0){ 1945 $('#faceboxContent #alerts').html(tag_groups_error_string()).show(); 1946 $('#' + errors[0]).focus(); 1947 }else{ 1948 var button = $(this).find('button'); 1949 button.attr('disabled', ''); 1950 var form = $(this); 1951 var copilot_check = form.find('#add_anchor'); 1952 copilot_check.removeAttr('disabled'); 1953 form.ajaxSubmit({ 1954 beforeSerialize : function() { 1955 popup_form_before_serialize(html); 1956 }, 1957 success: function(data) { 1958 if( copilot_check.length && copilot_check.is(':checked') ){ 1959 try { 1960 Excalibur.Ai.check_url(JSON.parse(data).url, true); 1961 $.facebox.close(); 1962 } 1963 catch (e) { 1964 if( data ) 1965 $.facebox(data); 1966 else 1967 $.facebox.close(); 1968 } 1969 } 1970 else 1971 popup_form_ajax_success(data, preprocess) || button.prop('disabled', false); 1972 }, 1973 error: function(){ 1974 button.prop('disabled', false); 1975 } 1976 }); 1977 } 1978 return false; 1979 }); 1980} 1981 1982function popup_form_before_serialize(html) { 1983 try { 1984 if (typeof(tinyMCE) != 'undefined'){ 1985 html = html.replace('[', '_'); 1986 html = html.replace(']', ''); 1987 1988 function cleanHTML(string) { 1989 if (string) { 1990 string = string.replace('<!DOCTYPE html>',''); 1991 string = string.replace('<html>',''); 1992 string = string.replace('</html>',''); 1993 string = string.replace('<head>',''); 1994 string = string.replace('</head>',''); 1995 string = string.replace('<body>',''); 1996 string = string.replace('</body>',''); 1997 string = string.replace(' class="_hovered"', ''); 1998 string = string.replace(/^\s+|\s+$/g, ''); 1999 } 2000 2001 return string; 2002 } 2003 2004 $('#' + html).html(cleanHTML(tinyMCE.activeEditor.getContent())); 2005 } else { 2006 var editor = FCKeditorAPI.GetInstance(html); 2007 html = html.replace('[', '\\['); 2008 html = html.replace(']', '\\]'); 2009 $('#' + html).val(editor.GetHTML()); 2010 } 2011 } catch(e) { 2012 } 2013} 2014 2015function tag_groups_error_string() { 2016 return '<div class="error alert_block" role="alert">
2016' + 2017 '<div class="alert_flex">' + 2018 '<div class="alert_icon">' + 2019 '<i class="error inverted"></i>' + 2020 '</div>' + 2021 //TODO: translate 2022 '<p>Please select the required tags.</p>' + 2023 '</div>' + 2024 '</div>'; 2025} 2026 2027// creating an alias so we don't change a lot of resources views 2028function popup_form_with_tag_groups(name) { 2029 resources_popup_form(name); 2030} 2031 2032// form_element should be a jQuery DOM object 2033function is_popup_form(form_element) { 2034 return form_element.closest('#faceboxContent').length > 0; 2035} 2036 2037// lessons 2038 2039function init_lessons(the_class_id, the_current_lesson_id, the_unhide_text, the_hide_text, the_confirm_text) { 2040 class_id = the_class_id; 2041 current_lesson_id = the_current_lesson_id; 2042 unhide_text = the_unhide_text; 2043 hide_text = the_hide_text; 2044 confirm_text = the_confirm_text; 2045} 2046 2047function show_section_adjustments(element) { 2048 $(element).find('> tbody').addClass('highlightLesson'); 2049 $(element).find('.accordionLink').attr("aria-expanded", true); 2050 $(element).find('.accordionLink > span:nth-of-type(1)').attr('class','hide'); 2051 $(element).find('.accordionLink > span:nth-of-type(2)').attr('class',''); 2052 2053 if (is_mobile_device() || $(element).find('tr').hasClass('current_lesson')) { 2054 $(element).find('.modern_module_row ~ tr').show(); 2055 } else { 2056 $(element).find('.modern_module_row ~ tr').show(400); 2057 } 2058} 2059 2060function hide_section_adjustments(element) { 2061 $(element).find('> tbody').removeClass('highlightLesson'); 2062 $(element).find('.accordionLink').attr("aria-expanded", false); 2063 $(element).find('.accordionLink > span:nth-of-type(1)').attr('class',''); 2064 $(element).find('.accordionLink > span:nth-of-type(2)').attr('class','hide'); 2065 $(element).find('.modern_module_row ~ tr').hide(); 2066} 2067 2068function teacher_show_sections(linkElement, showText, hideText, class_id) { 2069 $.ajax({ 2070 url : '/teacher_lessons/show_sections/' + class_id, 2071 success: function(){ 2072 $(linkElement).html('<i class="arrowUp"></i>'+hideText).attr('onclick', 'teacher_hide_sections(this, \''+showText+'\', \''+hideText+'\', '+class_id+')'); 2073 2074 show_section_adjustments($('.instructor_module_view > table')); 2075 update_min_height(); 2076 } 2077 }); 2078} 2079 2080function teacher_hide_sections(linkElement, showText, hideText, class_id) { 2081 $.ajax({ 2082 url : '/teacher_lessons/hide_sections/' + class_id, 2083 success: function() { 2084 $(linkElement).html('<i class="arrowDown"></i>'+showText).attr('onclick', 'teacher_show_sections(this, \''+showText+'\', \''+hideText+'\', '+class_id+')'); 2085 2086 hide_section_adjustments($('.instructor_module_view > table')); 2087 show_section_adjustments($('.instructor_module_view > table tr.current_lesson').parent().parent()); 2088 update_min_height(); 2089 } 2090 }); 2091} 2092 2093function student_show_sections(linkElement, showText, hideText, controller, class_id, child_id) { 2094 $.ajax({ 2095 url : '/' + controller + '/show_sections/' + class_id + (child_id == null ? '' : '?child=' + child_id), 2096 success: function() { 2097 $(linkElement).html('<i class="arrowUp"></i>'+hideText).attr('onclick', 'student_hide_sections(this, \''+showText+'\', \''+hideText+'\', \''+controller+'\', '+class_id+', '+child_id+')'); 2098 2099 show_section_adjustments($('.learner_module_view > table')); 2100 update_min_height(); 2101 } 2102 }); 2103} 2104 2105function student_hide_sections(linkElement, showText, hideText, controller, class_id, child_id) { 2106 $.ajax({ 2107 url : '/' + controller + '/hide_sections/' + class_id + (child_id == null ? '' : '?child=' + child_id), 2108 success: function() { 2109 $(linkElement).html('<i class="arrowDown"></i>'+showText).attr('onclick', 'student_show_sections(this, \''+showText+'\', \''+hideText+'\', \''+controller+'\', '+class_id+', '+child_id+')'); 2110 2111 hide_section_adjustments($('.learner_module_view > table')); 2112 show_section_adjustments($('.learner_module_view > table tr.current_lesson').parent().parent()); 2113 update_min_height(); 2114 } 2115 }); 2116} 2117 2118function ta_show_sections(linkElement, showText, hideText, class_id) { 2119 $.ajax({ 2120 url : '/teacher_lessons/show_sections/' + class_id, 2121 success: function() { 2122 $(linkElement).html('<i class="arrowUp"></i>'+hideText).attr('onclick', 'teacher_hide_sections(this, \''+showText+'\', \''+hideText+'\', '+class_id+')'); 2123 2124 show_section_adjustments($('.instructor_module_view > table')); 2125 update_min_height(); 2126 } 2127 }); 2128} 2129 2130function ta_hide_sections(linkElement, showText, hideText, class_id) { 2131 $.ajax({ 2132 url : '/teacher_lessons/hide_sections/' + class_id, 2133 success: function() { 2134 $(linkElement).html('<i class="arrowDown"></i>'+showText).attr('onclick', 'teacher_show_sections(this, \''+showText+'\', \''+hideText+'\', '+class_id+')'); 2135 2136 hide_section_adjustments($('.instructor_module_view > table')); 2137 show_section_adjustments($('.instructor_module_view > table tr.current_lesson').parent().parent()); 2138 update_min_height(); 2139 } 2140 }); 2141} 2142 2143// drag and drop 2144
2145function init_draggable_categories() { 2146 $("#category_list").sortable({ 2147 handle : 'td.draggable_handle', 2148 update : function(event, ui) { 2149 var after = ui.item.index('.draggable') + 1; 2150 var category_id = ui.item.find(':input:first').val(); 2151 window.location.href = '/class_catalog_categories/move/' + category_id + '?position=' + after; 2152 } 2153 }); 2154 2155 $("#category_list").disableSelection(); 2156} 2157 2158function init_draggable_categories_in_catalog() { 2159 var flex_height, 2160 tile_html; 2161 2162 $('.catalog_boxes.catalog_categories > div').mousedown(function(e) { 2163 flex_height = $(this).outerHeight(); 2164 tile_html = $(this).html(); 2165 }); 2166 2167 $(".catalog_boxes.catalog_categories").sortable({ 2168 revert: 300, 2169 containment: 'document', 2170 tolerance: 'pointer', 2171 handle : '.draggable_handle', 2172 placeholder: { 2173 // Added duplicated content so that the flex row stays the same height 2174 element: function() { 2175 return $('<div class="ui-sortable-placeholder" style="visibility:hidden">' + tile_html + '</div>'); 2176 }, 2177 update: function() { 2178 2179 } 2180 }, 2181 create: function (e, ui) { 2182 $('.catalog_boxes.catalog_categories.ui-sortable').removeClass('no_flex').show(); 2183 2184 // set width on container to fix last item in row glitch 2185 $('.hasRightColumn .catalog_boxes.catalog_categories.ui-sortable').css('width', $('.catalog_boxes.catalog_categories.ui-sortable').width()); 2186 }, 2187 start: function (e, ui) { 2188 // Set the height of ui-sortable-help so it doesn't change when removed from the flex flow 2189 ui.helper.css('height', flex_height); 2190 }, 2191 update : function(event, ui) { 2192 var after = ui.item.index('.catalog_categories > .draggable') + 1; 2193 var category_id = ui.item.attr('id'); 2194 2195 $.ajax({ 2196 url : '/class_catalog_categories/move/' + category_id + '?position=' + after + '&catalog=true', 2197 async : false 2198 }); 2199 } 2200 }); 2201 2202 $(".catalog_boxes.catalog_categories").disableSelection(); 2203} 2204 2205function init_draggable_items(category_id) { 2206 var flex_height, 2207 tile_html; 2208 2209 $('.catalog_boxes.catalog_courses > div').mousedown(function(e) { 2210 flex_height = $(this).outerHeight(); 2211 tile_html = $(this).html(); 2212 }); 2213 2214 $(".catalog_boxes.catalog_courses").sortable({ 2215 revert: 300, 2216 containment: 'document', 2217 tolerance: 'pointer', 2218 handle : '.draggable_handle', 2219 placeholder: { 2220 // Added duplicated content so that the flex row stays the same height 2221 element: function() { 2222 return $('<div class="ui-sortable-placeholder" style="visibility:hidden">' + tile_html + '</div>'); 2223 }, 2224 update: function() { 2225 2226 } 2227 }, 2228 create: function (e, ui) { 2229 $('.catalog_boxes.catalog_courses.ui-sortable').removeClass('no_flex').show(); 2230 2231 // set width on container to fix last item in row glitch 2232 $('.hasRightColumn .catalog_boxes.catalog_courses.ui-sortable').css('width', $('.catalog_boxes.catalog_courses.ui-sortable').width()); 2233 }, 2234 start: function (e, ui) { 2235 // Set the height of ui-sortable-help so it doesn't change when removed from the flex flow 2236 ui.helper.css('height', flex_height); 2237 }, 2238 update : function(event, ui) { 2239 var after = ui.item.index('.catalog_courses > .draggable') + 1; 2240 var category_item_id = ui.item.attr('category_item_id'); 2241 2242 $.ajax({ 2243 url : '/class_catalog_categories/move_item?category_id=' + category_id + '&category_item_id=' + category_item_id + '&position=' + after, 2244 async : false 2245 }); 2246 } 2247 }); 2248 2249 $(".catalog_boxes.catalog_courses").disableSelection(); 2250} 2251 2252function init_draggable_dashboard_items(selector, controller) { 2253 var flex_height, 2254 tile_html; 2255 2256 $(selector + ' > div').mousedown(function(e) { 2257 flex_height = $(this).outerHeight(); 2258 tile_html = $(this).html(); 2259 }); 2260 2261 $(selector).sortable({ 2262 revert: 300, 2263 containment: 'document', 2264 tolerance: 'pointer', 2265 handle : '.draggable_handle', 2266 placeholder: { 2267 // Added duplicated content so that the flex row stays the same height 2268 element: function() { 2269 return $('<div class="ui-sortable-placeholder" style="visibility:hidden">' + tile_html + '</div>'); 2270 }, 2271 update: function() { 2272 2273 } 2274 }, 2275 create: function (e, ui) { 2276 $(selector + '.ui-sortable').removeClass('no_flex').show(); 2277 2278 // set width on container to fix last item in row glitch 2279 $('.hasRightColumn ' + selector + '.ui-sortable').css('width', $(selector + '.ui-sortable').width()); 2280 }, 2281 start: function (e, ui) { 2282 // Set the height of ui-sortable-help so it doesn't change when removed from the flex flow 2283 ui.helper.css('height', flex_height); 2284 }, 2285 update : function(event, ui) { 2286 var order = []; 2287 var position = 0; 2288 2289 $.each($(selector + ' > .draggable'), function(i, v) { 2290 var info = $(v).data('order').split('_'); 2291 position++; 2292 order.push({position: position, id: info[1], type: info[0]}) 2293 }); 2294 2295 $.ajax({ 2296 type: 'POST', 2297 url: '/' + controller + '/move', 2298 async: false, 2299 data: {order: JSON.stringify(order)}, 2300 success: function(response) { 2301 var options = $('.optionsRibbon.optionsRight.optionsRibbon_multi_ul'); 2302 2303 if (options.find('a.reset_order').length == 0) { 2304 options.prepend('<ul><li><a href="/'+ controller +'/reset_order" excalibur-click="Excalibur.Router.load_left_column" title="' + reset_order_text + '" class="reset_order"><i class="refresh single"></i><span class="textOffScreen">' + reset_order_text + '</span></a></li></ul>'); 2305 } 2306 } 2307 }); 2308 } 2309 }); 2310 2311 $(".catalog_boxes.catalog_courses").disableSelection(); 2312} 2313 2314 2315function init_draggable_lessons(class_id) { 2316 var row_height;
2317 $('.instructor_module_view table').mousedown(function(e) { 2318 row_height = $(this).outerHeight(); 2319 }); 2320 2321 $(".instructor_module_view").sortable({ 2322 handle : '.draggable_handle', 2323 placeholder: { 2324 // Make the placeholder a different element so that it doesn't interfere with the :nth-child row coloring. 2325 element: function() { 2326 return $('<div class="ui-sortable-placeholder" style="visibility:hidden; height:' + row_height +'px"></div>'); 2327 }, 2328 update: function() { 2329 2330 } 2331 }, 2332 update : function(event, ui) { 2333 var after = ui.item.index('.draggable') + 1; 2334 var lesson_id = ui.item.find(':input:first').val(); 2335 2336 if (!lesson_id) { 2337 lesson_id = ui.item[0].id; 2338 } 2339 2340 $.ajax({ 2341 url : '/teacher_lessons/move/' + class_id + '?lesson_id=' + lesson_id + '&position=' + after, 2342 async : false 2343 }); 2344 } 2345 }); 2346 2347 $(".instructor_module_view").disableSelection(); 2348} 2349 2350function init_draggable_lessons_tiles(class_id) { 2351 var flex_height, 2352 tile_html, 2353 current_index; 2354 $('.lesson_boxes > div').mousedown(function(e) { 2355 flex_height = $(this).outerHeight(); 2356 tile_html = $(this).html().replace(/<a/g, '<div').replace(/<\/a>/g, '</div>'); 2357 current_index = $(this).parent().find('.imgCrop .current').closest('.draggable').index() + 1; 2358 }); 2359 2360 $(".lesson_boxes").sortable({ 2361 revert: 300, 2362 containment: 'document', 2363 tolerance: 'pointer', 2364 handle : '.draggable_handle', 2365 placeholder: { 2366 // Added duplicated content so that the flex row stays the same height 2367 element: function() { 2368 return $('<a class="ui-sortable-placeholder" style="visibility:hidden;">' + tile_html + '</a>'); 2369 }, 2370 update: function() { 2371 2372 } 2373 }, 2374 create: function (e, ui) { 2375 $('.lesson_boxes.ui-sortable').removeClass('no_flex').show(); 2376 2377 // set width on container to fix last item in row glitch 2378 $('.hasRightColumn .lesson_boxes.ui-sortable').css('width', $('.lesson_boxes.ui-sortable').width()); 2379 }, 2380 start: function (e, ui) { 2381 // Set the height of ui-sortable-help so it doesn't change when removed from the flex flow 2382 ui.helper.css('height', flex_height); 2383 }, 2384 update : function(event, ui) { 2385 var after = ui.item.index('.lesson_boxes > .draggable') + 1; 2386 var lesson_id = ui.item.find(':input:first').val(); 2387 2388 if (!lesson_id) { 2389 lesson_id = ui.item[0].id; 2390 } 2391 2392 var current_code = $('.lesson_boxes .imgCrop .current').clone(); 2393 $('.lesson_boxes .imgCrop .current').remove(); 2394 $('.lesson_boxes > div:nth-child(' + current_index + ') .imgCrop').prepend( current_code ); 2395 2396 $.ajax({ 2397 url : '/teacher_lessons/move/' + class_id + '?lesson_id=' + lesson_id + '&position=' + after, 2398 async : false 2399 }); 2400 } 2401 }); 2402 2403 $(".lesson_boxes").disableSelection(); 2404 2405 checkbox_highlight_tiles('.lesson_boxes'); 2406} 2407 2408function checkbox_highlight_tiles(container){ 2409 $(container + ' :checkbox').change(function(){ 2410 if($(this).is(':checked')){ 2411 $(this).closest(container + ' > *').addClass('highlight'); 2412 }else{ 2413 $(this).closest(container + ' > *').removeClass('highlight'); 2414 } 2415 }); 2416} 2417 2418function init_draggable_goals(path_id) { 2419 var row_height; 2420 2421 $('.goal_list table').mousedown(function(e) { 2422 row_height = $(this).outerHeight(); 2423 }); 2424 2425 $(".goal_list").sortable({ 2426 handle : '.draggable_handle', 2427 placeholder: { 2428 // Make the placeholder a different element so that it doesn't interfere with the :nth-child row coloring. 2429 element: function() { 2430 return $('<div class="ui-sortable-placeholder" style="visibility:hidden; height:' + row_height +'px"></div>'); 2431 }, 2432 update: function() { 2433 2434 } 2435 }, 2436 update : function(event, ui) { 2437 var after = ui.item.index('.draggable') + 1; 2438 var goal_id = ui.item.find(':input:first').val().replace("check_", ""); 2439 2440 $($('.goal_list h2 span span')).each( function(index) { 2441 $(this).text(index + 1); 2442 }); 2443 2444 $.ajax({ 2445 url : '/path_admin_goals/move/' + path_id + '?goal_id=' + goal_id + '&position=' + after, 2446 async : false 2447 }); 2448 } 2449 }); 2450 2451 $(".goal_list").disableSelection(); 2452} 2453 2454function init_draggable_bundle_items(bundle_id) { 2455 var row_height; 2456 2457 $('.goal_list table').mousedown(function(e) { 2458 row_height = $(this).outerHeight(); 2459 }); 2460 2461 $(".goal_list").sortable({ 2462 handle : '.draggable_handle', 2463 placeholder: { 2464 // Make the placeholder a different element so that it doesn't interfere with the :nth-child row coloring. 2465 element: function() { 2466 return $('<div class="ui-sortable-placeholder" style="visibility:hidden; height:' + row_height +'px"></div>'); 2467 }, 2468 update: function() { 2469 2470 } 2471 }, 2472 update : function(event, ui) { 2473 var after = ui.item.index('.draggable') + 1; 2474 var item_id = ui.item.find(':input:first').val().replace("check_", ""); 2475 2476 $($('.goal_list h2 span span')).each( function(index) { 2477 $(this).text(index + 1); 2478 }); 2479 2480 $.ajax({ 2481 url : '/bundle/move/' + bundle_id + '?item_id=' + item_id + '&position=' + after, 2482 async : false 2483 }); 2484 } 2485 }); 2486 2487 $(".goal_list").disableSelection(); 2488} 2489 2490function init_draggable_subscription_items(subscription_id) { 2491 var row_height; 2492
2493 $('.goal_list table').mousedown(function(e) { 2494 row_height = $(this).outerHeight(); 2495 }); 2496 2497 $(".goal_list").sortable({ 2498 handle : '.draggable_handle', 2499 placeholder: { 2500 // Make the placeholder a different element so that it doesn't interfere with the :nth-child row coloring. 2501 element: function() { 2502 return $('<div class="ui-sortable-placeholder" style="visibility:hidden; height:' + row_height +'px"></div>'); 2503 }, 2504 update: function() { 2505 2506 } 2507 }, 2508 update : function(event, ui) { 2509 var after = ui.item.index('.draggable') + 1; 2510 var item_id = ui.item.find(':input:first').val().replace("check_", ""); 2511 2512 $($('.goal_list h2 span span')).each( function(index) { 2513 $(this).text(index + 1); 2514 }); 2515 2516 $.ajax({ 2517 url : '/subscription/move/' + subscription_id + '?item_id=' + item_id + '&position=' + after, 2518 async : false 2519 }); 2520 } 2521 }); 2522 2523 $(".goal_list").disableSelection(); 2524} 2525 2526function init_draggable_sections(class_id, lesson_id) { 2527 $('#section_list').sortable({ 2528 handle : 'td.draggable_section_handle', 2529 update : function(event, ui) { 2530 var after = ui.item.index('.draggable') + 1; 2531 var section_id = ui.item.find(':input:first').val(); 2532 2533 $.ajax({ 2534 url : '/teacher_section/move/' + class_id + '?lesson_id=' + lesson_id + '§ion_id=' + section_id + '&position=' + after, 2535 async : false 2536 }); 2537 } 2538 }); 2539 2540 $('#section_list').disableSelection(); 2541} 2542 2543function init_draggable_levels(controller_path, game_id, id) { 2544 $('#levels_list').sortable({ 2545 handle : 'td.draggable_level_handle', 2546 update : function(event, ui) { 2547 let after = ui.item.index('.draggable') + 1; 2548 let level_id = ui.item.data('level'); 2549 let url = '/' + controller_path + '/move_level'; 2550 if(id) { 2551 url += '/' + id; 2552 } 2553 url += '?game=' + game_id + '&level_id=' + level_id + '&position=' + after, 2554 $.ajax({ 2555 url : url, 2556 async : false 2557 }); 2558 } 2559 }); 2560 2561 $('#section_list').disableSelection(); 2562} 2563 2564function init_draggable_questions(url, question_bank_id) { 2565 $("#question_list_" + question_bank_id).sortable({ 2566 handle : 'td.draggable_handle', 2567 update : function(event, ui) { 2568 var after = ui.item.index('.drag_list_' + question_bank_id) + 1; 2569 var question_id = ui.item.find(':input:first').val(); 2570 2571 $.ajax({ 2572 url: url + '?question_bank_id=' + question_bank_id + '&question_id=' + question_id + '&position=' + after, 2573 async : false 2574 }); 2575 } 2576 }); 2577 2578 $("#question_list").disableSelection(); 2579} 2580 2581function init_draggable_question_banks(url) { 2582 $("#question_bank_list").sortable({ 2583 handle: 'td.draggable_handle', 2584 update: function (event, ui) { 2585 var question_bank_id = ui.item.data('id'); 2586 var after = ui.item.index('.drag_bank_list') + 1; 2587 window.location = url + '?question_bank_id=' + question_bank_id + '&position=' + after; 2588 } 2589 }); 2590 2591 $("#question_bank_list").disableSelection(); 2592} 2593 2594function init_draggable_checkboxes(url, section_id) { 2595 $("#checkbox_list_" + section_id).sortable({ 2596 handle : 'td.draggable_handle', 2597 update : function(event, ui) { 2598 var after = ui.item.index('.drag_list_' + section_id) + 1; 2599 var checkbox_id = ui.item.find(':input:first').val(); 2600 2601 $.ajax({ 2602 url: url + '§ion_id=' + section_id + '&checkbox_id=' + checkbox_id + '&position=' + after, 2603 async : false 2604 }); 2605 } 2606}); 2607 2608$("#checkbox_list").disableSelection(); 2609} 2610 2611function init_draggable_resources() { 2612 $("#resource_list").sortable({ 2613 handle : 'td.draggable_handle', 2614 start : function(event, ui) { 2615 ui.item.data('before_block', resource_block_index(ui.item[0])); 2616 }, 2617 update : function(event, ui) { 2618 save_resource_position(ui.item, resource_row_position(ui.item)); 2619 move_resource_blocks(ui.item.data('before_block'), resource_block_index(ui.item[0])); 2620 redo_resource_move_states(); 2621 } 2622 }); 2623 2624 $("#resource_list").disableSelection(); 2625 2626 init_resource_move_controls(); 2627} 2628 2629function resource_rows() { 2630 return $('#resource_list tr.draggable'); 2631} 2632 2633function resource_row_position(row) { 2634 return resource_rows().index(row) + 1; 2635} 2636 2637// One save in flight at a time. insert_at reads the old position, shuffles the rows in 2638// between, then writes, with no transaction and no row lock (vendor/gems/acts_as_list 2639// .../list.rb:435), and #move does not wrap it either - so two overlapping saves read the 2640// same old_position, both shuffle, and can leave two rows sharing a position. Nothing 2641// errors when that happens, which is what makes it worth preventing on the client. 2642//
2643// Nothing is dispatched on unload for the same reason: anything sent then necessarily 2644// races the request already in flight, and a corrupt list is worse than a move that did 2645// not save. So a press made and then navigated away from within one round trip is lost. 2646// Closing that needs a transaction and a row lock in #move, which is a server change 2647// across every init_draggable_* caller and its own ticket. 2648// 2649// Deliberately not held on #resource_list: the router swaps the centre column out from 2650// under an in-flight save, and a queue tied to the table would strand its own tail. A 2651// window property rather than a top-level declaration, which a double include would 2652// throw on (see widgets.js). 2653function resource_move_queue() { 2654 window.resource_move_state = window.resource_move_state || { pending : [], sending : false }; 2655 2656 return window.resource_move_state; 2657} 2658 2659function send_next_resource_position() { 2660 const queue = resource_move_queue(); 2661 2662 if (queue.sending || !queue.pending.length) { 2663 return; 2664 } 2665 2666 // Off the queue at dispatch rather than at completion, so nothing can observe it as 2667 // still pending and send it a second time. 2668 const url = queue.pending.shift(); 2669 2670 queue.sending = true; 2671 2672 $.ajax({ url : url }).fail(function() { 2673 // The order on screen is no longer the stored one, so re-read it rather 2674 // than leave the user looking at a move that did not save. 2675 window.location.reload(); 2676 }).always(function() { 2677 queue.sending = false; 2678 send_next_resource_position(); 2679 }); 2680} 2681 2682function save_resource_position(row, position) { 2683 const url = $('#resource_list').data('move-url'); 2684 2685 // insert_at reads the old position, shuffles the rows in between, then writes, with 2686 // no transaction and no row lock (vendor/gems/acts_as_list .../list.rb:435). Presses 2687 // are quick enough to overlap, and two saves in flight can interleave against a stale 2688 // read and store an order that is not the one on screen - silently, since neither 2689 // request errors. Send them one at a time, in press order. 2690 resource_move_queue().pending.push( 2691 url + ((url.indexOf('?') == -1) ? '?' : '&') + 2692 'resource_id=' + row.find(':input:first').val() + '&position=' + position 2693 ); 2694 2695 send_next_resource_position(); 2696} 2697 2698 2699// The #resource_<n> content blocks below the table are numbered over non-folder 2700// resources only, so a row's block is the count of non-folder rows up to it. A folder 2701// row owns no block and returns 0: returning the running count would name the block of 2702// the nearest resource above it, which move_resource_blocks would then move instead. 2703function resource_block_index(row) { 2704 const rows = resource_rows().toArray(); 2705 let index = 0; 2706 2707 for (let i = 0; i < rows.length; i++) { 2708 const has_block = ($(rows[i]).find('a[href^="#resource_"]').length > 0); 2709 2710 if (has_block) { 2711 index++; 2712 } 2713 2714 if (rows[i] === row) { 2715 return has_block ? index : 0; 2716 } 2717 } 2718 2719 return 0; 2720} 2721 2722function move_resource_blocks(before, after) { 2723 if (!before || !after || (before == after)) { 2724 return; 2725 } 2726 2727 const moved = $('#resource_' + before)[0]; 2728 const target = $('#resource_' + after)[0]; 2729 2730 if (!moved || !target) { 2731 return; 2732 } 2733 2734 // Native move: .html() and the jQuery insert methods re-execute the block's <script src>. 2735 target.parentNode.insertBefore(moved, (after > before) ? target.nextSibling : target); 2736 2737 // The ids encode position, so renumber them for the next move. 2738 $(moved).parent().children('div[id^="resource_"]').each(function(index) { 2739 this.id = 'resource_' + (index + 1); 2740 }); 2741} 2742 2743function redo_resource_move_states() { 2744 const rows = resource_rows(); 2745 2746 rows.each(function(index) { 2747 $(this).find('.resource_move_up').attr('aria-disabled', (index === 0)); 2748 $(this).find('.resource_move_down').attr('aria-disabled', (index === (rows.length - 1))); 2749 }); 2750} 2751 2752function resource_move_announcer() { 2753 let announcer = $('#resource-move-announcer'); 2754 2755 if (!announcer.length) { 2756 // Lives on body: the router replaces the centre column wholesale, which would 2757 // destroy a region rendered inside the table.
2758 announcer = $('<div id="resource-move-announcer" class="sr-only" role="status" aria-live="polite"></div>').appendTo('body'); 2759 } 2760 2761 return announcer; 2762} 2763 2764function announce_resource_move(row, position) { 2765 const list = $('#resource_list'); 2766 const name = row.find('a').first().text().replace(/\s+/g, ' ').trim(); 2767 const text = name + ': ' + list.data('position-label') + ' ' + position + ' ' + 2768 list.data('of-label') + ' ' + resource_rows().length; 2769 const announcer = resource_move_announcer(); 2770 2771 setTimeout(function() { announcer.text(text); }, 0); 2772} 2773 2774function move_resource(el, direction) { 2775 if ($(el).attr('aria-disabled') == 'true') { 2776 return; 2777 } 2778 2779 const row = $(el).closest('tr'); 2780 const sibling = (direction == 'up') ? row.prev('tr') : row.next('tr'); 2781 2782 if (!sibling.length) { 2783 return; 2784 } 2785 2786 const before_block = resource_block_index(row[0]); 2787 2788 if (direction == 'up') { 2789 row.insertBefore(sibling); 2790 } else { 2791 row.insertAfter(sibling); 2792 } 2793 2794 const position = resource_row_position(row); 2795 2796 save_resource_position(row, position); 2797 move_resource_blocks(before_block, resource_block_index(row[0])); 2798 redo_resource_move_states(); 2799 announce_resource_move(row, position); 2800 2801 el.focus(); // the DOM move blurs it, and repeated moves need it back 2802} 2803 2804function init_resource_move_controls() { 2805 // The controls render under the high contrast theme only, so elsewhere there is 2806 // nothing to bind and no reason to leave a live region on the page. 2807 if (!$('#resource_list .resource_move').length) { 2808 return; 2809 } 2810 2811 resource_move_announcer(); // must pre-exist the first move or that move is not announced 2812 2813 // Delegated and namespaced: the router re-renders the table and init runs again with it. 2814 $(document).off('click.resource_move').on('click.resource_move', '#resource_list .resource_move', function() { 2815 move_resource(this, $(this).hasClass('resource_move_up') ? 'up' : 'down'); 2816 }); 2817} 2818 2819function init_draggable_slides(id) { 2820 $("#slide_list").sortable({ 2821 handle : 'td.draggable_handle', 2822 update : function(event, ui) { 2823 var after = ui.item.index('#slide_list .draggable') + 1; 2824 var slide_id = ui.item.find(':input:first').val(); 2825 var url = '/portal_slide/move/' + slide_id + '?portal_id=' + id + '&position=' + after; 2826 2827 $.ajax({ 2828 url : url, 2829 async : false 2830 }); 2831 } 2832 }); 2833 2834 $("#slide_list").disableSelection(); 2835} 2836 2837function init_draggable_panels(id) { 2838 $("#panel_list").sortable({ 2839 handle : 'td.draggable_handle', 2840 update : function(event, ui) { 2841 var after = ui.item.index('#panel_list .draggable') + 1; 2842 var panel_id = ui.item.find(':input:first').val(); 2843 var url = '/portal_panel/move/' + panel_id + '?portal_id=' + id + '&position=' + after; 2844 2845 $.ajax({ 2846 url : url, 2847 async : false 2848 }); 2849 } 2850 }); 2851 2852 $("#panel_list").disableSelection(); 2853} 2854 2855function init_draggable_menu_items(id) { 2856 $("#menu_list").sortable({ 2857 handle : 'td.draggable_handle', 2858 update : function(event, ui) { 2859 var after = ui.item.index('#menu_list .draggable') + 1; 2860 var menu_id = ui.item.find(':input:first').val(); 2861 var url = '/portal_menu/move/' + menu_id + '?portal_id=' + id + '&position=' + after; 2862 2863 $.ajax({ 2864 url : url, 2865 async : false 2866 }); 2867 } 2868 }); 2869 2870 $("#menu_list").disableSelection(); 2871} 2872 2873function init_draggable_footer_items(id) { 2874 $("#footer_list").sortable({ 2875 handle : 'td.draggable_handle', 2876 update : function(event, ui) { 2877 var after = ui.item.index('#footer_list .draggable') + 1; 2878 var footer_id = ui.item.find(':input:first').val(); 2879 var url = '/portal_footer/move/' + footer_id + '?portal_id=' + id + '&position=' + after; 2880 2881 $.ajax({ 2882 url : url, 2883 async : false 2884 }); 2885 } 2886 }); 2887 2888 $("#footer_list").disableSelection(); 2889} 2890 2891function init_draggable_boxes(name, the_id, controller) { 2892 var tbody_id = "#" + name + "_list"; 2893 2894 $(tbody_id).sortable({ 2895 handle : 'td.draggable_handle', 2896 update : function(event, ui) { 2897 var after = ui.item.index(tbody_id + ' .draggable') + 1; 2898 var box_id = ui.item.find(':input:first').val(); 2899 2900 $.ajax({ 2901 url : '/' + controller + '/move/' + the_id + '?box_id=' + box_id + '&position=' + after, 2902 async : false 2903 }); 2904 } 2905 }); 2906 2907 $(tbody_id).disableSelection(); 2908} 2909 2910function init_draggable_policy_documents(controller) { 2911 $("#policy_documents_list").sortable({ 2912 handle : 'td.draggable_handle', 2913 update : function(event, ui) { 2914 var after = ui.item.index('#policy_documents_list .draggable') + 1; 2915 var policy_document_id = ui.item.find(':input:first').val(); 2916 2917 $.ajax({ 2918 url : '/' + controller + '/move/' + policy_document_id + '?position=' + after, 2919 async : false 2920 }); 2921 } 2922 }); 2923 2924 $("#shortcuts_list").disableSelection(); 2925} 2926 2927function init_draggable_invoice_templates(controller) { 2928 $("#invoice_templates_list").sortable({ 2929 handle : 'td.draggable_handle', 2930 update : function(event, ui) { 2931 var after = ui.item.index('#invoice_templates_list .draggable') + 1; 2932 var invoice_template_id = ui.item.find(':input:first').val(); 2933 2934 $.ajax({ 2935 url : '/' + controller + '/move/' + invoice_template_id + '?position=' + after, 2936 async : false 2937 }); 2938 } 2939 }); 2940 2941 $("#shortcuts_list").disableSelection(); 2942} 2943 2944function init_draggable_shortcuts() { 2945 $("#shortcuts_list").sortable({ 2946 handle : 'td.draggable_handle', 2947 update : function(event, ui) { 2948 var after = ui.item.index('#shortcuts_list .draggable') + 1; 2949 var shortcut_id = ui.item.find(':input:first').val(); 2950 2951 $.ajax({ 2952 url : '/shortcuts/move/' + shortcut_id + '?position=' + after, 2953 async : false 2954 }); 2955 } 2956 }); 2957 2958 $("#shortcuts_list").disableSelection(); 2959} 2960 2961function init_draggable_footers() { 2962 $("#footers_list").sortable({ 2963 handle : 'td.draggable_handle', 2964 update : function(event, ui) { 2965 var after = ui.item.index('#footers_list .draggable') + 1; 2966 var picture_id = ui.item.find(':input:first').val(); 2967 2968 $.ajax({
2969 url : '/footers/move/' + picture_id + '?position=' + after, 2970 async : false 2971 }); 2972 } 2973 }); 2974 2975 $("#footers_list").disableSelection(); 2976} 2977 2978function init_draggable_tiers() { 2979 $("#tier_list").sortable({ 2980 handle : 'td.draggable_handle', 2981 update : function(event, ui) { 2982 var after = ui.item.index('.draggable') + 1; 2983 var tier_id = ui.item.find(':input:first').val(); 2984 $.get('/subscription_tiers/move/' + tier_id + '?position=' + after); 2985 } 2986 }); 2987 2988 $("#category_list").disableSelection(); 2989} 2990 2991function init_draggable_quiz_items() { 2992 var in_dropzone = false; 2993 2994 $('.quiz_match_choice').draggable({ 2995 containment: '.leftColumn', 2996 start: function(event, ui) { 2997 $(this).attr('aria-grabbed','true'); 2998 $('.quiz_match_dropzone').attr('aria-dropeffect','move'); 2999 3000 $('.quiz_match_table').addClass('quiz_match_highlight'); 3001 }, 3002 stop: function(event, ui) { 3003 $(this).attr('aria-grabbed','false'); 3004 $('.quiz_match_dropzone').attr('aria-dropeffect','none'); 3005 3006 $('.quiz_match_table').removeClass('quiz_match_highlight'); 3007 if (!in_dropzone) { 3008 $(this).appendTo($('.quiz_match_choices')); 3009 var answer_total = 0; 3010 $('.quiz_match_dropzone input').each(function(){ 3011 answer_total += parseInt($(this).val()); 3012 }); 3013 if(answer_total == parseInt($(this).data('index'))){ 3014 $('.quiz_match_dropzone input').removeAttr('name'); 3015 } 3016 } 3017 $(this).removeAttr('style'); 3018 //refresh answers 3019 $('.quiz_match_dropzone').each(function(index){ 3020 if($(this).find('.quiz_match_choice').length == 0){ 3021 $(this).find('input').val(0); 3022 } 3023 }); 3024 } 3025 }); 3026 3027 $('.quiz_match_dropzone').droppable({ 3028 tolerance: 'pointer', 3029 over: function(event, ui) { 3030 $(this).addClass('quiz_match_over'); 3031 }, 3032 out: function(event, ui) { 3033 in_dropzone = false; 3034 $(this).removeClass('quiz_match_over'); 3035 }, 3036 drop: function(event, ui) { 3037 in_dropzone = true; 3038 $(this).removeClass('quiz_match_over'); 3039 $(this).find('.quiz_match_choice').appendTo($('.quiz_match_choices')); 3040 ui.draggable.appendTo($(this)).removeAttr('style'); 3041 $(this).find('input').val(ui.draggable.data('index')); 3042 $('.quiz_match_dropzone input').each(function(){ 3043 $(this).attr('name', $(this).data('name')); 3044 }); 3045 } 3046 }); 3047 3048 if($('.quiz_match_choices > div').length > 0){ 3049 // randomize choices in the front end 3050 var $quiz_match_choices = document.getElementsByClassName('quiz_match_choices')[0]; 3051 for (var i = $quiz_match_choices.children.length; i >= 0; i--) { 3052 $quiz_match_choices.appendChild($quiz_match_choices.children[Math.random() * i | 0]); 3053 } 3054 } 3055 3056 // show chices after they are randomized 3057 $('.quiz_match_choices > div').show(); 3058 3059 $('.quiz_match_choices').droppable({ 3060 tolerance: 'pointer', 3061 over: function(event, ui) { 3062 $('.quiz_match_choices').addClass('quiz_match_over'); 3063 }, 3064 out: function(event, ui) { 3065 $('.quiz_match_choices').removeClass('quiz_match_over'); 3066 }, 3067 drop: function(event, ui) { 3068 $('.quiz_match_choices').removeClass('quiz_match_over'); 3069 } 3070 }); 3071 3072 $(document).keydown( 3073 function(e) { 3074 // When within .quiz_match 3075 if ($(':focus').closest('.quiz_match').length > 0) { 3076 3077 // Right / Down arrow 3078 if (e.keyCode == 39 || e.keyCode == 40) { 3079 if ($('.tabbable').index($(':focus')) + 1 == $('.tabbable').length) { 3080 $('.tabbable').eq(0).focus(); 3081 } else { 3082 $('.tabbable').eq($('.tabbable').index($(':focus')) + 1).focus(); 3083 } 3084 } 3085 3086 // Up / Left arrow 3087 if (e.keyCode == 37 || e.keyCode == 38) { 3088 $('.tabbable').eq($('.tabbable').index($(':focus')) - 1).focus(); 3089 } 3090 3091 // Space bar / Enter 3092 if(e.which == 32 || e.keyCode == 13) { 3093 3094 if ($(':focus').hasClass('quiz_match_choice')) { 3095 // Selected a choice 3096 3097 $('.quiz_match_table').addClass('quiz_match_highlight'); // add class to table 3098 $('.quiz_match_dropzone').attr('aria-dropeffect','move'); // highlight portential dropzones 3099 3100 // Make empty dropzones tabbable 3101 $(".quiz_match_dropzone").each(function(index) { 3102 if ($(this).children().length == 0) { 3103 $(this).addClass('tabbable').attr('tabindex',0); 3104 } 3105 }); 3106 3107 if ($(':focus').parent().hasClass('quiz_match_dropzone')) { 3108 // If selecting a choice inside a dropzone 3109 3110 $(':focus').parent().removeClass('tabbable').attr('tabindex',null); // prevent tab to this choice's dropzone 3111 3112 if ($('.ui-draggable-dragging').length > 0) { 3113 // If already dragging a choice 3114 // Add in selected dropzone 3115 $('.ui-draggable-dragging').appendTo($(':focus').parent()); 3116 $(':focus').appendTo($('.quiz_match_choices')); 3117 // Highlight the first option in the options holder 3118 $('.quiz_match_choices > div:first-child').focus(); 3119 remove_quiz_match_highlight(); 3120 } else { 3121 // If not dragging a choice 3122 3123 $('.quiz_match_choices').attr('aria-dropeffect','move').addClass('tabbable').attr('tabindex',0); 3124 $(':focus').attr('aria-grabbed','true').addClass('ui-draggable-dragging'); 3125 } 3126 3127 } else { 3128 // If selecting a choice in choices div 3129 3130 if ($('.ui-draggable-dragging').length > 0) { 3131 // If already dragging a choice 3132 // Insert after selected choice 3133 $('.ui-draggable-dragging').insertAfter($(':focus')); 3134 // Highlight focussed item 3135 $('.ui-draggable-dragging').focus(); 3136 remove_quiz_match_highlight(); 3137 } else { 3138 // If not dragging a choice 3139 3140 $('.quiz_match_choice').attr('aria-grabbed','false').removeClass('ui-draggable-dragging'); // remove any drag classes 3141 $(':focus').attr('aria-grabbed','true').addClass('ui-draggable-dragging'); // add new drag class 3142 } 3143 } 3144 3145 } else if ($(':focus').hasClass('quiz_match_dropzone')) { 3146 // Selected a dropzone 3147 3148 if ($(':focus > div').length == 0) { 3149 in_dropzone = true; 3150 $('.ui-draggable-dragging').appendTo($(':focus')); // append choice to the dropzone 3151 3152 if ($('.quiz_match_choices > div').length != 0) { 3153 // Highlight the first option in the options holder 3154 $('.quiz_match_choices > div:first-child').focus(); 3155 } else { 3156 // Highlight the current option 3157 $('.ui-draggable-dragging').focus(); 3158 } 3159 } 3160 remove_quiz_match_highlight(); 3161 3162 } else if ($(':focus').hasClass('quiz_match_choices')) { 3163 // Select the choices div 3164 3165 $('.ui-draggable-dragging').appendTo($('.quiz_match_choices')); 3166 $('.quiz_match_choices > div:first-child').focus(); 3167 remove_quiz_match_highlight(); 3168 } 3169 3170 } 3171 3172 function remove_quiz_match_highlight() { 3173 $('.ui-draggable-dragging').attr('aria-grabbed','false').removeClass('ui-draggable-dragging'); 3174 $('div[aria-dropeffect="move"]').attr('aria-dropeffect','none'); 3175 $('.quiz_match_table').removeClass('quiz_match_highlight'); 3176 $('.quiz_match_choices, .quiz_match_dropzone').removeClass('tabbable').attr('tabindex',null); 3177 } 3178 3179 } 3180 } 3181 ); 3182} 3183 3184function set_carousel_speed(panel_id, select, portal_id) { 3185 $.ajax({ 3186 url : '/carousel_panel/set_speed/' + panel_id + '?portal_id=' + portal_id + '&value=' + select.value, 3187 async : false 3188 }); 3189} 3190 3191// libraries 3192 3193function update_libraries(url, return_url) { 3194 var checkboxes = $('input.library_checkbox'); 3195 var file_search = $('#file-search'); 3196 var name = $('input#compact_filter_phrase').length ? $('input#compact_filter_phrase') : file_search; 3197 var person = $('input#users'); 3198 3199 for (var i = 0; i < checkboxes.length; i += 1) { 3200 var checkbox = checkboxes[i]; 3201 3202 if (checkbox.checked) { 3203 url += '&' + checkbox.name + '=true'; 3204 } 3205 } 3206 3207 var users_filter = $('#users_filter'); 3208 3209 if (users_filter.length > 0) { 3210 url += '&users[]=' + users_filter.val(); 3211 } 3212 3213 if( Excalibur.File_explorer.override_view_type ){ 3214 url += '&view_type=' + Excalibur.File_explorer.override_view_type; 3215 } 3216 3217 var subject_filter = $('#subject_filter'); 3218 3219 if (subject_filter.length > 0) { 3220 url += '&subject=' + subject_filter.val(); 3221 } 3222 3223 var classification_filter = $('#classification_filter'); 3224 3225 if (classification_filter.length > 0) { 3226 if (resources_file_formats.includes(classification_filter.val())) { 3227 url += '&format=' + classification_filter.val(); 3228 } else { 3229 url += '&classification=' + classification_filter.val(); 3230 } 3231 } 3232 var filter_bar = $('.type-filter-bar'); 3233 if( filter_bar.length ){ 3234 if( filter_bar.find('> div[type].selected').length ) 3235 url += '&format=' + filter_bar.find('> div[type].selected').attr('type'); 3236 else if( filter_bar.find('div li[type].selected').length ) 3237 url += '&classification=' + filter_bar.find('div li[type].selected').attr('type'); 3238 } 3239 3240 var filter_bar = $('.type-filter-bar'); 3241 if( filter_bar.length ){ 3242 if( filter_bar.find('> div[type].selected').length ) 3243 url += '&format=' + filter_bar.find('> div[type].selected').attr('type'); 3244 else if( filter_bar.find('div li[type].selected').length ) 3245 url += '&classification=' + filter_bar.find('div li[type].selected').attr('type'); 3246 } 3247 3248 if (name.val() != '') { 3249 url += '&name=' + encodeURIComponent(name.val()); 3250 } 3251 3252 if ((person.length > 0) && (person.val().trim() != '')) { 3253 url += '&users=' + encodeURIComponent(person.val().trim()); 3254 } 3255 3256 url += '&filter_active=true'; 3257 3258 var sort_url = $('th .asc, th .desc').attr('href'); 3259 3260 if (typeof sort_url != 'undefined' && sort_url.length > 0){ 3261 sort_val = get_param_from_url(sort_url, 'sort'); 3262 if (typeof sort_val != 'undefined' && sort_val.length > 0) { 3263 sort_val = (sort_val.indexOf('-') !== -1 ) ? sort_val.replace('-', '')
3263: (sort_val + '-'); 3264 url += '&sort=' + sort_val 3265 } 3266 } else { 3267 sort_val = get_param_from_url(window.location.href, 'sort'); 3268 if (typeof sort_val != 'undefined' && sort_val.length > 0) { 3269 url += '&sort=' + sort_val 3270 } 3271 } 3272 3273 url = update_library_tag_groups_url(url); 3274 3275 if( file_search.length ){ 3276 if(return_url) 3277 return url; 3278 else 3279 Excalibur.Router.load(url, '.file-explorer'); 3280 } 3281 else 3282 window.location.href = url; 3283} 3284 3285function update_library_tag_groups_url(url) { 3286 if($('.library_tag_group').length > 0){ 3287 var tag_ids = []; 3288 $('.library_tag_group').each(function(){ 3289 if($(this).val().length > 0){ 3290 tag_ids.push($(this).val()); 3291 } 3292 }); 3293 3294 var tags_query = 'tags=' + tag_ids.join(','); 3295 url = decodeURIComponent(url); 3296 3297 if (url.indexOf('?') == -1) { 3298 url = url + '?from_form=true&' + tags_query; 3299 } else if(url.indexOf('tags=') > -1) { 3300 url = url.replace(/tags=[0-9,]{0,}/i, tags_query); 3301 if(tag_ids.length == 0) { 3302 url = url.replace('tags=', ''); 3303 } 3304 } else { 3305 url = url + '&' + tags_query; 3306 } 3307 } 3308 3309 return url; 3310} 3311 3312function update_library_tag_groups() { 3313 var url = window.location.href; 3314 url = update_library_tag_groups_url(url); 3315 window.location.href = url; 3316} 3317 3318// policy documents 3319 3320function set_policy_document_enabled(controller, policy_document_id, checkbox) { 3321 ajax_request('/' + controller + '/set_enabled/' + policy_document_id + '?value=' + check_s(checkbox)); 3322} 3323 3324// help desk 3325 3326function set_help_desk_org_restriction(checkbox) { 3327 ajax_request('/help_desk_configure/set_organization_restriction?value=' + check_s(checkbox)); 3328} 3329 3330// URL parameter parsing 3331 3332function get_args(url) { 3333 var args = []; 3334 var question = url.indexOf('?'); 3335 3336 if (question != -1) { 3337 var params = url.substring(question + 1).split('&'); 3338 3339 for (var i = 0; i < params.length; i++) { 3340 var pair = params[i].split('='); 3341 args[pair[0]] = pair[1]; 3342 } 3343 } 3344 3345 return args; 3346} 3347 3348// configure sync 3349 3350function sync_now(el, sync_type, org_id) { 3351 var el = $(el); 3352 var query = '?return_controller=' + sync_type; 3353 3354 var users_radio = $('input[name="sync[users_from]"]:checked'); 3355 var sections_radio = $('input[name="sync[sections_from]"]:checked'); 3356 3357 if (users_radio.length > 0) { 3358 query = query + '&users=' + users_radio.val(); 3359 } 3360 3361 if (sections_radio.length > 0) { 3362 //if (query.length == 0) { 3363 // query = query + '?'; 3364 // } else { 3365 // query = query + '&'; 3366 //} 3367 3368 query = query + '§ions=' + sections_radio.val(); 3369 } 3370 3371 if (org_id !== undefined){ 3372 query = query + '&org_id=' + org_id; 3373 } 3374 3375 window.location = '/sis/sync' + query; 3376} 3377 3378function one_roster_sync_now(el, sync_type, org_id) { 3379 var el = $(el); 3380 var query = '?return_controller=' + sync_type; 3381 3382 var users_radio = $('input[name="sync[users_from]"]:checked'); 3383 var sections_radio = $('input[name="sync[sections_from]"]:checked'); 3384 3385 if (users_radio.length > 0) { 3386 query = query + '&users=' + users_radio.val(); 3387 } 3388 3389 if (sections_radio.length > 0) { 3390 query = query + '§ions=' + sections_radio.val(); 3391 } 3392 3393 if (org_id !== undefined){ 3394 query = query + '&org_id=' + org_id; 3395 } 3396 3397 window.location = '/one_roster/sync' + query; 3398} 3399 3400function sync_organization_now(el, sync_type, org_id) { 3401 var el = $(el); 3402 var query = '?return_controller=' + sync_type; 3403 3404 var users_radio = $('input[name="sync[users_from]"]:checked'); 3405 var sections_radio = $('input[name="sync[sections_from]"]:checked'); 3406 3407 if (users_radio.length > 0) { 3408 query = query + '&users=' + users_radio.val(); 3409 } 3410 3411 if (sections_radio.length > 0) { 3412 query = query + '§ions=' + sections_radio.val(); 3413 } 3414 3415 if (org_id !== undefined){ 3416 query = query + '&org_id=' + org_id; 3417 } 3418 3419 window.location = '/sis/sync_organization' + query; 3420} 3421 3422function new_sync_now(el, c, args) { 3423 var el = $(el); 3424 var autoCommitCheckBox= document.getElementById("auto_commit"); 3425 var bypassCommitThresholdCheckBox= document.getElementById("bypass_commit_threshold"); 3426 var checks = $('#sis_schools input[type="checkbox"]:checked').map(function() { 3427 return $(this).val(); 3428 }).get() 3429 3430 query = '?auto_commit=' + autoCommitCheckBox.checked + '&bypass_commit_threshold=' + bypassCommitThresholdCheckBox.checked + '&schools=' +checks; 3431 window.location = '/one_roster/' + args + query; 3432} 3433 3434function csv_sync_schools(el, c, id) { 3435 let users_radio = $('input[name="sync[users_from]"]:checked'); 3436 let sections_radio = $('input[name="sync[sections_from]"]:checked'); 3437 let checkBox = document.getElementById("auto_commit"); 3438 3439 query = '?auto_commit=' + checkBox.checked; 3440 3441 if (id !== -1) { 3442 query = query + '&schools=' + id; 3443 } else {
3444 let checks = $('#sis_schools tbody input[type="checkbox"]:checked').map(function() { 3445 return $(this).val(); 3446 }).get(); 3447 3448 query = query + '&schools=' + checks; 3449 } 3450 3451 if (users_radio.length > 0) { 3452 query = query + '&users=' + users_radio.val(); 3453 } 3454 3455 if (sections_radio.length > 0) { 3456 query = query + '§ions=' + sections_radio.val(); 3457 } 3458 3459 window.location = '/csv_sis/prepare_schools' + query; 3460} 3461 3462function sync_setting(checkbox, id, attribute) { 3463 ajax_request('/sis/update_setting/' + id + '?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 3464} 3465 3466function sync_other_settings(element, id, attribute) { 3467 ajax_request('/sis/update_setting/' + id + '?attribute=' + attribute + '&value=' + element.value); 3468} 3469 3470function sync_organization_setting(checkbox, id, attribute) { 3471 ajax_request('/sis/update_organization_setting/' + id + '?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 3472} 3473 3474function sync_organization_other_settings(element, id, attribute) { 3475 ajax_request('/sis/update_organization_setting/' + id + '?attribute=' + attribute + '&value=' + element.value); 3476} 3477 3478function sync_sso_activate(select, id) { 3479 $.confirm({ 3480 confirm: function() { 3481 ajax_request('/clever_sso/update/' + id + '?clever_enabled=' + select.value); 3482 }, 3483 cancel: function() { 3484 if (select.value == 'true') { 3485 select.value = 'false'; 3486 } else { 3487 select.value = 'true'; 3488 } 3489 } 3490 }); 3491} 3492 3493function sync_auto_activate(select, id) { 3494 $.confirm({ 3495 confirm: function() { 3496 ajax_request('/sis/set_auto_sync/' + id + '?sis_auto_sync=' + select.value); 3497 }, 3498 cancel: function() { 3499 if (select.value == 'true') { 3500 select.value = 'false'; 3501 } else { 3502 select.value = 'true'; 3503 } 3504 } 3505 }); 3506} 3507 3508function sync_organization_auto_activate(select, id) { 3509 $.confirm({ 3510 confirm: function() { 3511 ajax_request('/sis/set_organization_auto_sync/' + id + '?sis_auto_sync=' + select.value); 3512 }, 3513 cancel: function() { 3514 if (select.value === 'true') { 3515 select.value = 'false'; 3516 } else { 3517 select.value = 'true'; 3518 } 3519 } 3520 }); 3521} 3522 3523function sync_check_for_ids(id) { 3524 $('a.start-onboarding').on('click', function(){ 3525 var interval = setInterval(function(){ 3526 $.ajax({ 3527 type: "POST", 3528 url: "/clever/check_if_district_is_set", 3529 data: {id: id}, 3530 dataType: "json", 3531 success: function(data) { 3532 console.log(data); 3533 3534 if (data.status == 'success') { 3535 clearInterval(interval); 3536 window.location = '/clever'; 3537 } 3538 } 3539 }); 3540 }, 2500); 3541 }); 3542} 3543 3544function one_roster_execute_query() { 3545 var query = $("#console").val(); 3546 3547 $('#QueryResultsWrapper').html('<h2>Please wait...</h2>'); 3548 3549 $.get('/one_roster/execute_query', {query: query, ajax_request: true}, function(html) { 3550 $('#QueryResultsWrapper').html(html); 3551 to_load(); 3552 }); 3553} 3554 3555// waitlist approval 3556 3557function update_waitlist_approval(class_id, radio_button) { 3558 window.location.href = '/class_configure/set_waitlist_approval/' + class_id + '?value=' + radio_button.value; 3559} 3560 3561// update access 3562 3563function update_visibility(url, radio_button) { 3564 window.location.href = url + (url.includes('?') ? '&' : '?') + 'value=' + radio_button.value; 3565} 3566 3567function update_locking(url, radio_button) { 3568 window.location.href = url + (url.includes('?') ? '&' : '?') + 'value=' + radio_button.value; 3569} 3570 3571// configure account 3572 3573function account_setting(checkbox, attribute, refresh) { 3574 if (refresh) { 3575 $.post('/account/set_attribute?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false'), function() { 3576 stash_settings_focus(checkbox); 3577 location.reload(); 3578 }) 3579 } else { 3580 ajax_request('/account/set_attribute?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 3581 } 3582} 3583 3584// WCAG 3.2.2 (On Input): stash the changed control's id before the reload so restore_settings_focus() can return keyboard focus to it afterward. 3585// Timestamped because the reload is not guaranteed: a failed POST or an abandoned navigation would otherwise leave the id behind to steal focus on a later unrelated page load. 3586 3587function stash_settings_focus(el) { 3588 if (el && el.id) { 3589 try { sessionStorage.setItem('settings_refocus_id', JSON.stringify({id: el.id, at: Date.now()})); 3590 } catch (e) { 3591 console.error('stash_settings_focus: sessionStorage unavailable', e); 3592 } 3593 } 3594} 3595 3596function restore_settings_focus() { 3597 const max_age_ms = 10000; 3598 3599 let raw; 3600 try { raw = sessionStorage.getItem('settings_refocus_id'); 3601 } catch (e) { 3602 console.error('restore_settings_focus: sessionStorage unavailable', e); 3603 return; 3604 } 3605 3606 if (!raw) return; 3607 3608 try { sessionStorage.removeItem('settings_refocus_id'); 3609 } catch (e) { 3610 console.error('restore_settings_focus: could not clear stashed id', e); 3611 } 3612 3613 let stash; 3614 try { stash = JSON.parse(raw); 3615 } catch (e) { 3616 console.error('restore_settings_focus: could not parse stashed value', e); 3617 return; 3618 } 3619 3620 if (!stash || !stash.id) return; 3621 3622 // ignore a stash whose reload never happened 3623 if ((Date.now() - stash.at) > max_age_ms) return; 3624 3625 const el = document.getElementById(stash.id); 3626 if (el && typeof el.focus === 'function') el.focus(); 3627} 3628 3629// high contrast theme toggle 3630 3631function high_contrast_theme_toggle() { 3632 var current_state = $('link[title="theme"]').attr('href').includes('high_contrast'); 3633 var new_value = !current_state; 3634 3635 account_setting({checked: new_value}, 'use_accessible_theme', true); 3636} 3637 3638// configure privacy setting 3639 3640function privacy_setting(checkbox, attribute, refresh) { 3641 if (refresh) { 3642 $.post('/profile_privacy/set_attribute?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false'), function() { 3643 location.reload(); 3644 }) 3645 } else { 3646 ajax_request('/profile_privacy/set_attribute?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 3647 } 3648} 3649 3650function set_top_tab(radio) { 3651 stash_settings_focus(radio); 3652 window.location.href = '/account/set_top_tab?value=' + encodeURIComponent(radio.value); 3653} 3654 3655// mini-navigation 3656 3657function language_setting(dropdown) { 3658 window.location.href = '/account/set_language?value=' + encodeURIComponent(dropdown.value); 3659} 3660 3661function time_zone_setting(dropdown) { 3662 ajax_request('/account/set_time_zone?value=' + encodeURIComponent(dropdown.value)); 3663} 3664 3665function set_user_session_timeout(dropdown) { 3666 window.location.href = '/account/set_session_timeout?value=' + dropdown.value; 3667} 3668 3669function google_docs_setting(checkbox) { 3670 if (checkbox.checked) { 3671 window.location.href = '/google_docs_configure/enable'; 3672 } else { 3673 window.location.href = '/google_docs_configure/disable'; 3674 } 3675} 3676 3677function infinite_scroll(container, callback) { 3678 $(container).scroll(function(e) { 3679 if (e.target.scrollTop >= (e.target.scrollHeight - e.target.clientHeight)) { 3680 callback(); 3681 $(container).unbind('scroll'); 3682 } 3683 }); 3684} 3685 3686function set_unsubscribed_from_newsletter(checkbox) { 3687 ajax_request('/account/set_unsubscribed_from_newsletter?value=' + (checkbox.checked ? 'false' : 'true')); 3688} 3689 3690function google_drive_docs_activation_checkbox(el) { 3691 if (el.checked == true) { 3692 var wi = window.open('/google_drive/enable', 'Google Drive Authorization', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=no, copyhistory=no, width=600, height=750'); 3693 3694 check_google_drive_docs_activation(wi); 3695 } else { 3696 $.confirm({ 3697 content : 'Are you sure you want to deactivate Google Drive?', 3698 confirm : function() { 3699 $.ajax({ 3700 type : "POST", 3701 url : "/google_drive/disable", 3702 dataType : "json", 3703 success : function(json) { 3704 if (json.status == 'ok') { 3705 location.reload(); 3706 } else if (json.status == 'bad') { 3707 $.alert({ 3708 content : 'Couldn\'t disable Google Drive.' 3709 }); 3710 } else { 3711 $.alert({ 3712 content : 'Something went wrong.' 3713 }); 3714 } 3715 } 3716 }); 3717 } 3718 }); 3719 } 3720} 3721 3722function google_drive_docs_activation(auto_open_add_popup = true) { 3723 var wi = window.open('/google_drive/enable', 'Google Drive Authorization', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=no, copyhistory=no, width=600, height=750'); 3724 check_google_drive_docs_activation(wi, auto_open_add_popup ? 'auto' : null); 3725} 3726 3727function check_google_drive_docs_activation(wi, type){ 3728 var counter = 0; 3729 3730 var interval = setInterval(function(){ 3731 $.ajax({ 3732 type: "POST", 3733 url: "/google_drive/check_activation", 3734 dataType: "json", 3735 async: false, 3736 success: function(json){ 3737 if (json.status == 'ok') { 3738 if (type == 'auto') { 3739 $.facebox({'ajax':'/google_docs/add'}); 3740 clearInterval(interval); 3741 } else { 3742 location.reload(); 3743 } 3744 } 3745 } 3746 }); 3747 3748 counter++; 3749 3750 if (counter == 40) { 3751 wi.close(); 3752 clearInterval(interval); 3753 3754 $.alert({content: 'The process took too long!'}); 3755 } 3756 }, 2000); 3757} 3758 3759function google_drive_docs_disable() { 3760 $.ajax({ 3761 type: "POST", 3762 url: "/google_drive/disable", 3763 dataType: "json", 3764 success: function(json) { 3765 if (json.status == 'ok') { 3766 google_drive_enable(); 3767 } else if (json.status == 'bad') { 3768 $.alert({content: 'Couldn\'t disable Google Drive.'}); 3769 } else { 3770 $.alert({content: 'Something went wrong.'}); 3771 } 3772 } 3773 }); 3774} 3775 3776function onedrive_activation_checkbox(el, business) { 3777 if (business && (business == true)) { 3778 var controller = 'one_drive_business'; 3779 var service = 'OneDrive for Business'; 3780 } else { 3781 var controller = 'one_drive'; 3782 var service = 'OneDrive'; 3783 } 3784 3785 if (el.checked == true) { 3786 var wi = window.open('/' + controller + '/enable', service + ' Authorization', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=no, copyhistory=no, width=600, height=750'); 3787 3788 check_onedrive_activation(wi, el, business); 3789 } else { 3790 $.confirm({ 3791 content : 'Are you sure you want to deactivate ' + service + '?', 3792 cancel: function() { 3793 $(el).attr('checked', true); 3794 }, 3795 confirm : function() { 3796 $.ajax({ 3797 type : "POST", 3798 url : "/" + controller + "/disable", 3799 dataType : "json", 3800 success : function(json) { 3801 if (json.status == 'ok') { 3802 location.reload(); 3803 } else if (json.status == 'bad') { 3804 $(el).attr('checked', false); 3805 3806 $.alert({ 3807 content : 'Couldn\'t disable ' + service + '.' 3808 }); 3809 } else { 3810 $(el).attr('checked', false); 3811 3812 $.alert({ 3813 content : 'Something went wrong.' 3814 }); 3815 } 3816 } 3817 }); 3818 } 3819 }); 3820 } 3821} 3822 3823function check_onedrive_activation(wi, el, business){ 3824 if (business && (business == true)) { 3825 var controller = 'one_drive_business'; 3826 } else { 3827 var controller = 'one_drive'; 3828 } 3829 3830 var counter = 0; 3831 3832 var interval = setInterval(function(){ 3833 $.ajax({ 3834 type: "POST", 3835 url: "/" + controller + "/check_activation", 3836 dataType: "json", 3837 async: false, 3838 success: function(json){ 3839 if (json.status == 'ok') { 3840 location.reload(); 3841 } else { 3842 $(el).attr('checked', false); 3843 } 3844 } 3845 }); 3846 3847 counter++; 3848 3849 if (counter == 40) { 3850 wi.close(); 3851 clearInterval(interval); 3852 3853 $(el).attr('checked', false); 3854 $.alert({content: 'The process took too long!'}); 3855 } 3856 }, 2000); 3857} 3858 3859function google_meet_access(iframe) { 3860 var wi = window.open('/google_meet/authorize', 'Google Meet Authorization', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=no, copyhistory=no, width=600, height=750'); 3861 check_google_meet_access(wi, iframe); 3862} 3863 3864function google_meet_access_checkbox(el) { 3865 if (el.checked == true) { 3866 var wi = window.open('/google_meet/authorize', 'Google Meet Authorization', 'toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=no, copyhistory=no, width=600, height=750'); 3867 check_google_meet_access(wi, window); 3868 } else { 3869 $.confirm({ 3870 content : 'Are you sure you want to deactivate Google Meet?', 3871 confirm : function() { 3872 $.ajax({ 3873 type : "POST", 3874 url : "/google_meet/disable", 3875 dataType : "json", 3876 success : function(json) { 3877 if (json.status == 'ok') { 3878 location.reload(); 3879 } else if (json.status == 'bad') { 3880 $.alert({ 3881 content : 'Couldn\'t disable Google Meet.' 3882 }); 3883 } else { 3884 $.alert({ 3885 content : 'Something went wrong.' 3886 }); 3887 } 3888 } 3889 }); 3890 } 3891 }); 3892 } 3893} 3894 3895function check_google_meet_access(wi, iframe){ 3896 var counter = 0; 3897 3898 var interval = setInterval(function(){ 3899 $.ajax({ 3900 type: "POST", 3901 url: "/google_meet/check_activation", 3902 dataType: "json", 3903 async: false, 3904 success: function(json){ 3905 if (json.status == 'ok') { 3906 wi.close(); 3907 clearInterval(interval); 3908 iframe.location.reload(); 3909 } 3910 } 3911 }); 3912 3913 counter++; 3914 3915 if (counter == 50) { 3916 wi.close(); 3917 clearInterval(interval); 3918 3919 $.alert({content: 'The process took too long!'}); 3920 } 3921 }, 2000); 3922} 3923 3924// configure catalog 3925 3926function configure_catalog(attribute, invert, checkbox) { 3927 var value = ( invert ? !checkbox.checked : checkbox.checked); 3928 ajax_request('/class_catalogs_configure/set_attribute?attribute=' + attribute + '&value=' + (value == true ? 'true' : 'false')); 3929} 3930 3931// class catalog 3932 3933function jump_to_class(controller, dropdown) { 3934 if (dropdown.value && (dropdown.value != 0)) { 3935 window.location.href = '/' + controller + '/show/' + dropdown.value; 3936 } 3937} 3938 3939// pop-ups 3940 3941function update_home_popup(value) { 3942 ajax_request('/home/display_popup?value=' + (value ? 'true' : 'false'), {asynchronous : false}); 3943} 3944 3945function update_ui_popup(value) { 3946 ajax_request('/home/display_ui_popup?value=' + (value ? 'true' : 'false'), {asynchronous : false}); 3947} 3948 3949function update_teacher_popup(class_id, value) { 3950 ajax_request('/teacher_class/display_popup/' + class_id + '?value=' + (value ? 'true' : 'false'), {asynchronous : false}); 3951} 3952 3953function update_student_popup(class_id, value) { 3954 ajax_request('/student_class/display_popup/' + class_id + '?value=' + (value ? 'true' : 'false'), {asynchronous : false}); 3955} 3956 3957// configure attribute 3958 3959function configure_attribute(attribute, controller, object_id, checkbox) { 3960 ajax_request('/' + controller + '/set_attribute/' + object_id + '?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 3961} 3962 3963function configure_attribute_and_refresh(attribute, controller, object_id, checkbox, from) { 3964 window.location.href = '/' + controller + '/set_attribute_and_refresh/' + object_id + '?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false') + '&from=' + from; 3965} 3966 3967// configure compliance 3968 3969function configure_compliance(controller, object_id, checkbox) { 3970 window.location.href = '/' + controller + '/set_required_for_compliance/' + object_id + '?value=' + (checkbox.checked ? 'true' : 'false'); 3971} 3972 3973// configure class 3974 3975function configure_class(attribute, class_id, checkbox) { 3976 ajax_request('/class_configure/set_attribute/' + class_id + '?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 3977} 3978 3979function configure_class_and_refresh(attribute, class_id, checkbox, from) { 3980 window.location.href = '/class_configure/set_attribute_and_refresh/' + class_id + '?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false') + '&from=' + from; 3981} 3982 3983function configure_enable_lessons_grid_view(class_id, checkbox) { 3984 window.location.href = '/class_configure/enable_lessons_grid_view/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false'); 3985} 3986 3987function configure_enable_lessons_row_view(class_id, checkbox) { 3988 window.location.href = '/class_configure/enable_lessons_row_view/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false'); 3989} 3990 3991function configure_class_inverted(attribute, class_id, checkbox) { 3992 ajax_request('/class_configure/set_attribute/' + class_id + '?
3992attribute=' + attribute + '&value=' + (checkbox.checked ? 'false' : 'true')); 3993} 3994 3995function configure_site_wide_restriction(controller, the_id, game_id, checkbox, from) { 3996 ajax_request('/' + controller + '/set_only_for_site_wide/' + the_id + '?game=' + game_id + '&value=' + (checkbox.checked ? 'true' : 'false') + '&from=' + encodeURIComponent(from)); 3997} 3998 3999function configure_game_enabled(controller, the_id, game_id, checkbox, from) { 4000 ajax_request('/' + controller + '/set_enabled/' + the_id + '?game=' + game_id + '&value=' + (checkbox.checked ? 'true' : 'false') + '&from=' + encodeURIComponent(from)); 4001} 4002 4003function configure_game(controller, the_id, attribute, game_id, checkbox) { 4004 ajax_request('/' + controller + '/set_attribute/' + the_id + '?game=' + game_id + '&attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 4005} 4006 4007function configure_leaderboard(controller, the_id, game_id, checkbox, from) { 4008 window.location.href = '/' + controller + '/set_leaderboard/' + the_id + '?game=' + game_id + '&value=' + (checkbox.checked ? 'true' : 'false') + '&from=' + encodeURIComponent(from); 4009} 4010 4011function configure_game_teams(controller, the_id, game_id, checkbox, from) { 4012 window.location.href = '/' + controller + '/set_support_teams/' + the_id + '?game=' + game_id + '&value=' + (checkbox.checked ? 'true' : 'false') + '&from=' + encodeURIComponent(from); 4013} 4014 4015function set_student_top_tab(class_id, radio_button) { 4016 ajax_request('/class_configure/set_student_top_tab/' + class_id + '?attribute=' + radio_button.value); 4017} 4018 4019function set_teacher_top_tab(class_id, radio_button) { 4020 ajax_request('/class_configure/set_teacher_top_tab/' + class_id + '?attribute=' + radio_button.value); 4021} 4022 4023function set_path_tile_display(class_id, radio_button) { 4024 ajax_request('/class_configure/set_path_tile_display/' + class_id + '?attribute=' + radio_button.value); 4025} 4026 4027function configure_open_enrollment(class_id, checkbox) { 4028 ajax_request('/class_configure/set_open_enrollment/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 4029} 4030 4031function configure_reenrollment(class_id, checkbox, reload) { 4032 var url = '/class_configure/set_reenrollment/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false'); 4033 if (reload) { 4034 window.location.href = url; 4035 } else { 4036 ajax_request(url); 4037 } 4038} 4039 4040function configure_repurchase(class_id, checkbox) { 4041 ajax_request('/class_configure/set_repurchase/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 4042} 4043 4044function configure_enable_grades(class_id, checkbox) { 4045 window.location.href = '/class_configure/set_enable_grades/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false'); 4046} 4047 4048function configure_enable_grade_map(class_id, checkbox) { 4049 window.location.href = '/class_configure/set_enable_grade_map/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false'); 4050} 4051 4052function configure_enable_rubrics(class_id, checkbox) { 4053 window.location.href = '/class_configure/set_enable_rubrics/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false'); 4054} 4055 4056function set_class_default_grade_release(class_id, value) { 4057 ajax_request('/class_configure/set_default_grade_release/' + class_id + '?value=' + value); 4058} 4059 4060function set_class_rubric_points_ordering(class_id, value) { 4061 ajax_request('/class_configure/set_rubric_points_ordering/' + class_id + '?value=' + value); 4062} 4063 4064function configure_enable_student_posts(class_id, checkbox) { 4065 window.location.href = '/class_configure/set_enable_student_posts/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false'); 4066} 4067 4068function set_class_announcement_comments(class_id, checkbox) { 4069 ajax_request('/class_configure/set_announcement_comments/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 4070} 4071 4072function set_weight_using_categories(class_id, checkbox) { 4073 window.location.href = '/class_configure/set_weight_using_categories/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false'); 4074} 4075 4076function configure_weighting(class_id, scheme) { 4077 ajax_request('/class_configure/set_weighting/' + class_id + '?value=' + scheme); 4078} 4079 4080function configure_lessons_in_order(class_id, checkbox) { 4081 ajax_request('/class_configure/set_lessons_in_order/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 4082} 4083 4084function configure_sections_in_order(class_id, checkbox) { 4085 ajax_request('/class_configure/set_sections_in_order/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 4086} 4087 4088function configure_auto_complete_on_visit(class_id, checkbox) { 4089 ajax_request('/class_configure/set_auto_complete_on_visit/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 4090} 4091 4092function configure_require_video_completion(class_id, checkbox) { 4093 ajax_request('/class_configure/set_require_video_completion/' + class_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 4094} 4095 4096function update_app_request(school_id, name, title, checkbox) { 4097 $.confirm({ 4098 content: ($(checkbox).is(":checked") ? "Are you sure you want to enable " + title + " so the customer can install it?" : "Are you sure you want to un-enable " + title + "?"), 4099 confirm: function() { 4100 window.location.href = '/school/update_app_request/' + school_id + '?name=' + name + '&value=' + (checkbox.checked ? 'true' : 'false'); 4101 }, 4102 cancel: function() { 4103 if ($(checkbox).is(":checked")) 4104 $(checkbox).prop( "checked", false ); 4105 else 4106 $(checkbox).prop( "checked", true ); 4107 } 4108 }); 4109} 4110 4111function set_mastery_calculation2(dropdown) { 4112 if (dropdown.value == 'Decaying average') { 4113 $('#decaying_average_weight').show(); 4114 } else { 4115 $('#decaying_average_weight').hide(); 4116 } 4117} 4118 4119function set_mastery_value_threshold2(dropdown) { 4120 if (dropdown.value == '') { 4121 $('#mastery_count_threshold').hide(); 4122 $('#mastery_progress_calculation').hide(); 4123 } else { 4124 $('#mastery_count_threshold').show(); 4125 $('#mastery_progress_calculation').show(); 4126 } 4127} 4128 4129// section configuration 4130 4131function set_section_optional_for_completion(class_id, lesson_id, section_id, checkbox) { 4132 ajax_request('/teacher_section/set_optional_for_completion/' + class_id + '?lesson_id=' + lesson_id + '§ion_id=' + section_id + '&value=' + (checkbox.checked ? 'false' : 'true')); 4133} 4134 4135function set_assignment_optional_for_completion(assignment_id, checkbox) { 4136 ajax_request('/teacher_assignment/set_optional_for_completion/' + assignment_id + '?value=' + (checkbox.checked ? 'false' : 'true')); 4137} 4138 4139// lesson configuration 4140 4141function set_lesson_optional_for_completion(class_id, lesson_id, checkbox) { 4142 ajax_request('/teacher_lesson/set_optional_for_completion/' + class_id + '?lesson_id=' + lesson_id + '&value=' + (checkbox.checked ? 'false' : 'true')); 4143} 4144 4145// path configuration 4146 4147function set_path_feature(path_id, checkbox) { 4148 ajax_request('/path_configure/set_attribute/' + path_id + '?attribute=' + checkbox.value + '&value=' + (checkbox.checked ? 'true' : 'false')); 4149} 4150 4151function configure_open_enrollment_path(path_id, checkbox) { 4152 ajax_request('/path_configure/set_open_enrollment/' + path_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 4153} 4154 4155function set_path_announcement_comments(path_id, checkbox) { 4156 ajax_request('/path_configure/set_announcement_comments/' + path_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 4157} 4158 4159function set_sequencing(path_id, radio_button) { 4160 ajax_request('/path_configure/set_sequencing/' + path_id + '?value=' + radio_button.value); 4161} 4162 4163function configure_enable_path_student_posts(path_id, checkbox) { 4164 ajax_request('/path_configure/set_enable_student_posts/' + path_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 4165} 4166 4167function configure_path(attribute, path_id, checkbox) { 4168 ajax_request('/path_configure/set_attribute/' + path_id + '?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 4169} 4170 4171// goal configuration 4172 4173function set_goal_optional_for_completion(path_id, goal_id, checkbox) { 4174 ajax_request('/path_admin_goal/set_optional_for_completion/' + path_id + '?goal=' + goal_id + '&value=' + (checkbox.checked ? 'false' : 'true')); 4175} 4176 4177// bundles 4178 4179function configure_bundle(attribute, bundle_id, checkbox) { 4180 ajax_request('/bundle_configure/set_attribute/' + bundle_id + '?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 4181} 4182 4183// subscriptions 4184 4185function configure_subscription(attribute, subscription_id, checkbox) { 4186 ajax_request('/subscription_configure/set_attribute/' + subscription_id + '?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 4187} 4188 4189// logo 4190 4191function set_left_bar_picture(value) { 4192 ajax_request('/logo/set_left_bar_picture?value=' + value); 4193} 4194 4195// tile color 4196 4197function configure_tile_color(controller, object_id, value){ 4198 if(/^([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(value)){ 4199 ajax_request('/' + controller + '/set_tile_color/' + object_id + '?value=' + encodeURIComponent('#' + value)); 4200 } 4201} 4202 4203function configure_recommendations(type, checkbox) { 4204 ajax_request('/goals_admin/configure_recommendation?type=' + type + '&value=' + (checkbox.checked ? 'true' : 'false')); 4205} 4206 4207function configure_goals(type, checkbox) { 4208 ajax_request('/goals_admin/configure_goal?type=' + type + '&value=' + (checkbox.checked ? 'true' : 'false')); 4209} 4210 4211function update_checkbox_response(id, section_id, checkbox_id, checkbox) { 4212 ajax_request('/student_checkbox_section/update_checkbox_response/' + id + '?section_id=' + section_id + '&checkbox_id=' + checkbox_id + '&value=' + (checkbox.checked ? 'true' : 'false')); 4213} 4214 4215// tile color 4216 4217var reset_color; 4218 4219function submit_quick_tile_editor(box_index, controller, object_id, lesson_id, lesson_index, game) { 4220 var name = $('#tile_name_' + box_index).val(); 4221 var tile_color = '#' + $('#tile_color_' + box_index).val(); 4222 if($('#tile_picture_' + box_index).length > 0){ 4223 var picture = $('#tile_picture_' + box_index).val(); 4224 } 4225 var $parent_obj = $('[id^="quick_edit_box_' + box_index + '_"]').parent(); 4226 4227 // name 4228 var name_element = $('#tile_name_' + box_index); 4229 4230 if (name_element.length) { 4231 var name = name_element.val(); 4232 } 4233 4234 // color 4235 var tile_element = $('#tile_color_' + box_index); 4236 4237 if (tile_element.length) { 4238 var tile_color_value = tile_element.val().replace(/\s/g, ""); 4239 var tile_color = tile_color_value === 'transparent' ? 'transparent' : '#' + tile_color_value; 4240 } 4241 4242 // picture 4243 var tile_picture_element = $('#tile_picture_' + box_index); 4244 4245 if (tile_picture_element.length) { 4246 var picture = tile_picture_element.val(); 4247 } 4248 4249 // values 4250 var values = {}; 4251 4252 if (typeof name != 'undefined' && name.length > 0) { 4253 values['name'] = name; 4254 } 4255 4256 reset_color_button_id = '#reset_tile_color_' + (lesson_id ? lesson_id : object_id); 4257 4258 if (reset_color || typeof reset_color == 'undefined') { 4259 // only repaint on an explicit reset: when the color was never touched the 4260 // picker still holds the tile's own color (seeded from --tile-color-bar), 4261 // so painting it here would flood the tile body with its bar color 4262 if (reset_color) { 4263 if ($parent_obj.parent().prop('tagName') == "TD" ){ 4264 $parent_obj.parent().css('background-color', tile_color); 4265 } else { 4266 $parent_obj.css('background-color', tile_color); 4267 } 4268 } 4269 $(reset_color_button_id).hide(); 4270 if (typeof lesson_index != 'undefined') { 4271 JSON.stringify(values['tile_color'],null) 4272 } 4273 } else if (typeof tile_color != 'undefined' && (tile_color === 'transparent' || tile_color === '#' || (tile_color.length > 1 && /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(tile_color)))) { 4274 values['tile_color'] = tile_color === '#' ? '' : tile_color; 4275 $(reset_color_button_id).show(); 4276 } 4277 4278 if (typeof picture != 'undefined' && picture.length > 0) { 4279 values['picture'] = picture; 4280 } 4281 4282 if (typeof game != 'undefined') { 4283 values['game'] = game; 4284 } 4285 4286 if (!$.isEmptyObject(values)) { 4287 // in the case of lessons, object_id is the class_id and we also pass the lesson_id 4288 $.post('/' + controller + '/set_quick_tile_values/' + object_id + (typeof lesson_id != 'undefined' ? '?lesson_id=' + lesson_id : ''), values, function () { 4289 for (var key in values) { 4290 switch (key) { 4291 case 'name': 4292 if ($parent_obj.parents('.has_quick_editor').length > 0) { 4293 4294 if (lesson_index){ 4295 tile_name = lesson_index + '. '+ values[key]; 4296 }else { 4297 tile_name = values[key]; 4298 } 4299 if ($parent_obj.parents('.modern_module_list').length > 0){ 4300 $parent_obj.siblings().children('div.header').children().children('h2 > span, h3 > span').html(tile_name); 4301 } else { 4302 // catalog/lesson/group tiles use h2.class_name, dashboard class and path tiles use h3.class_name 4303 $parent_obj.children('div.header').children().children('h2, h3').html(tile_name); 4304 } 4305 4306 }else{ 4307 if($('#fixedSectionHeader').length > 0){ 4308 $('#fixedSectionHeader .centerHeading a').html(values[key]); 4309 } else if ($('.teacherLessonHeading').length > 0) { 4310 $('.teacherLessonHeading .centerHeading a').html(values[key]); 4311 } else { 4312 $('.sectionTitle h2, .sectionTitle h1, #leftColumn h1').html(values[key]); 4313 } 4314 } 4315 break; 4316 case 'tile_color': 4317 if ($('body').hasClass('catalog_class')) { 4318 $('head').append('<style>' + 4319 'html:not([dir=rtl]) .catalog_class #contentWrap:before,' + 4320 '[dir=rtl] .catalog_class #contentWrap:after,' + 4321 '.catalog_class #leftColumn {' + 4322 'background-color: ' + values[key] + 4323 '}
4323' + 4324 '</style>'); 4325 } else { 4326 var tile_id = box_index.replace(/^[a-z_]+/, ''); 4327 var $tile_element = $('#' + tile_id); 4328 4329 if ($tile_element.attr('data-tile-color-bar') === 'true') { 4330 $tile_element.css('--tile-color-bar', values[key]); 4331 } else { 4332 if ($parent_obj.parent().hasClass('modern_module_wrap')) { 4333 $parent_obj.parent().css('background-color', values[key]); 4334 } else { 4335 $parent_obj.css('background-color', values[key]); 4336 } 4337 } 4338 } 4339 4340 break; 4341 case 'picture': 4342 if ($parent_obj.parents('.has_quick_editor').length > 0) { 4343 $parent_obj.find('.imgCrop').css('background-image', 'url(\'' + values[key] + '\')'); 4344 } else { 4345 if ($('body').hasClass('catalog_class')) { 4346 $('.leftColumn .imgCrop').css('background-image', 'url(\'' + values[key] + '\')'); 4347 } else { 4348 if ($('.leftColumn .img_crop_wrap > img').length > 0) { 4349 console.log('updating img src'); 4350 $('.leftColumn .img_crop_wrap > img').attr('src', values[key]); 4351 } else { 4352 console.log('updating div bg image'); 4353 if (lesson_id) { 4354 $(`.leftColumn #${lesson_id} .imgCrop`).css('background-image', 'url(\'' + values[key] + '\')'); 4355 } else { 4356 $(`.leftColumn #${object_id} .imgCrop`).css('background-image', 'url(\'' + values[key] + '\')'); 4357 } 4358 } 4359 } 4360 } 4361 4362 // Clear input fields so user can make multiple changes without refreshing 4363 var uploaderWrapperId = 'UploaderWrapper' + box_index; 4364 var $uploaderWrapper = $('#' + uploaderWrapperId); 4365 $uploaderWrapper.find('#SingleFileUpload').remove(); 4366 $uploaderWrapper.hide(); 4367 $uploaderWrapper.siblings('.optionsRibbon, .action-toolbar').show(); 4368 4369 break; 4370 } 4371 } 4372 }); 4373 } 4374} 4375 4376//default image editor 4377function submit_image_editor(image) { 4378 var $url_input = $('#tile_picture_' + image); 4379 if($url_input.length > 0 && $url_input.val().length > 0){ 4380 var url = $url_input.val(); 4381 var $parent_obj = $('#quick_edit_box_' + image).parent(); 4382 var values = { 4383 image: image, 4384 url: url 4385 }; 4386 4387 $.post('/custom_tile_images/save_image/', values, function() { 4388 $parent_obj.find('.imgCrop').css('background-image', 'url(\'' + values.url +'\')'); 4389 $parent_obj.removeClass('default_image'); 4390 }); 4391 } 4392} 4393 4394function reset_tile_picture(image){ 4395 var box_id = '#quick_edit_box_' + image; 4396 $tile = $(box_id).parent(); 4397 $.post('/custom_tile_images/delete_image/', {image: image}, function() { 4398 $tile.find('.imgCrop').css('background-image', 'url(\'' + $tile.data('original_url') +'\')'); 4399 $(box_id).hide(); 4400 $tile.addClass('default_image'); 4401 }); 4402} 4403 4404function submit_image_job_title(id) { 4405 var $url_input = $('#job_title_picture_' + id); 4406 if($url_input.length > 0 && $url_input.val().length > 0){ 4407 var url = $url_input.val(); 4408 var $parent_obj = $('#quick_edit_box_' + id).parent(); 4409 var values = { 4410 url: url 4411 }; 4412 4413 $.post('/job_title/save_image/' + id, values, function () { 4414 $parent_obj.css('background-image', 'url(\'' + url + '\')'); 4415 }); 4416 } 4417} 4418 4419function reset_job_title_picture(id){ 4420 var box_id = '#quick_edit_box_' + id; 4421 $tile = $(box_id).parent(); 4422 $.post('/job_title/delete_image/' + id, function () { 4423 $tile.css('background-image', 'url(\'' + $tile.data('original_url') + '\')'); 4424 $(box_id).hide(); 4425 }); 4426} 4427 4428// mastery image quick edit 4429 4430function submit_image_curriculum(id) { 4431 var $url_input = $('#curriculum_picture_' + id); 4432 if($url_input.length > 0 && $url_input.val().length > 0){ 4433 var url = $url_input.val(); 4434 var $parent_obj = $('#quick_edit_box_' + id).parent(); 4435 var values = { 4436 url: url 4437 }; 4438 4439 $.post('/mastery/save_image/' + id, values, function () { 4440 $parent_obj.css('background-image', 'url(\'' + url + '\')'); 4441 }); 4442 } 4443} 4444 4445function reset_curriculum_picture(id){ 4446 var box_id = '#quick_edit_box_' + id; 4447 $tile = $(box_id).parent(); 4448 $.post('/mastery/delete_image/' + id, function () { 4449 $tile.css('background-image', 'url(\'' + $tile.data('original_url') + '\')'); 4450 $(box_id).hide(); 4451 }); 4452} 4453 4454// submit and reset cover photo 4455 4456function submit_background_photo(replace_image) { 4457 if($('#background_photo').length > 0){ 4458 var photo = $('#background_photo').val(); 4459 } 4460 if(typeof photo != 'undefined' && photo.length > 0){ 4461 $.post('/user/submit_background_photo', { photo: photo }, function( data ) { 4462 if (replace_image) { 4463 $('.profile_background').css('background-image', 'url(\'' + photo +'\')'); 4464 } else { 4465 show_info(data.message) 4466 } 4467 }); 4468 } 4469} 4470 4471function reset_background_photo(theme_cover) { 4472 $.post('/user/remove_background_photo', {}, function() { 4473 $('.profile_background').css('background-image', 'url(\'' + theme_cover + '\')'); 4474 }); 4475} 4476 4477function init_quick_edit_box(box_id){ 4478 $box = $(box_id); 4479 $box.find('.options_btn').hide(); 4480 $box.find('.uploader-list').show(); 4481} 4482 4483function update_tile_color_input(input_id, color){ 4484 reset_color = false;
4485 4486 $(input_id).siblings('button').show(); 4487 4488 if (color === 'transparent') { 4489 // Handle transparent separately - set empty value for jscolor 4490 $(input_id).css('background-color', 'transparent').val(''); 4491 } else { 4492 $(input_id).css('background-color', color).val(color.replace('#', '')); 4493 } 4494} 4495 4496function reset_tile_color(controller, object_id, input_id, lesson_id, game){ 4497 reset_color = true; 4498 var child, child_id; 4499 var attributes = ''; 4500 4501 if (lesson_id) { 4502 attributes = '&lesson_id=' + lesson_id.toString(); 4503 child_id = lesson_id.toString(); 4504 } else if (game) { 4505 attributes = '&game=' + game.toString(); 4506 child_id = game.toString(); 4507 } else { 4508 child_id = object_id; 4509 } 4510 4511 if ($('#'+ child_id ).prop('tagName') == 'TABLE'){ 4512 child = $('table#' + child_id)[0]; 4513 } else { 4514 child = $('div#' + child_id)[0]; 4515 } 4516 var parent = child.parentNode; 4517 var position = Array.prototype.indexOf.call(parent.children, child); 4518 4519 color = Functions.Helpers.hexc($('.tile_colors.m_r_auto')[0].children[position % 4].style.backgroundColor).toUpperCase(); 4520 4521 default_color_index = (position % 4 + 1); 4522 4523 $(input_id).css('background-color', color).val(color.replace('#', '')); 4524 4525 reset_color_button_id = '#reset_tile_color_' + child_id; 4526 $(reset_color_button_id).hide(); 4527 4528 ajax_request('/' + controller + '/set_tile_color/' + object_id + '?value=' + default_color_index + attributes); 4529} 4530 4531// EVO UI: Reset tile color to original value from the tile element 4532function reset_tile_color_evo(input_id) { 4533 reset_color = false; 4534 4535 var $input = $(input_id); 4536 4537 // Find the tile element 4538 var $quickEditBox = $input.closest('.quick_edit_box'); 4539 var $tile = null; 4540 4541 // Case 1: Tile view - the parent div has data-tile-color-bar (e.g., <div class="draggable" ...>) 4542 var $parent = $quickEditBox.parent(); 4543 if ($parent.attr('data-tile-color-bar') === 'true') { 4544 $tile = $parent; 4545 } 4546 4547 // Case 2: List view - look for a td.modern_module_wrap ancestor with data-tile-color-bar 4548 if (!$tile) { 4549 $tile = $quickEditBox.closest('.modern_module_wrap[data-tile-color-bar="true"]'); 4550 } 4551 4552 // Get the initial color from the --tile-color-bar CSS variable 4553 var initialColor = 'transparent'; 4554 if ($tile && $tile.length > 0 && $tile.attr('data-tile-color-bar') === 'true') { 4555 var tileColorBar = window.getComputedStyle($tile[0]).getPropertyValue('--tile-color-bar').trim(); 4556 if (tileColorBar && tileColorBar !== 'transparent') { 4557 initialColor = tileColorBar.startsWith('#') ? tileColorBar : Functions.Helpers.hexc(tileColorBar); 4558 } 4559 } 4560 4561 $input.css('background-color', initialColor).val(initialColor.replace('#', '')); 4562 4563 if ($input[0].jscolor) { 4564 $input[0].jscolor.fromString(initialColor); 4565 } 4566 4567 $input.siblings('button').show(); 4568} 4569 4570// fonts 4571 4572function select_font(dropdown) { 4573 window.location.href = '/portal/set_font?value=' + dropdown.value; 4574} 4575 4576function select_font_size(dropdown) { 4577 window.location.href = '/portal/set_font_size?value=' + dropdown.value; 4578} 4579 4580// icons 4581 4582function set_icon_for_profile(checkbox) { 4583 window.location.href = '/icons/set_icon_for_profile?value=' + check_s(checkbox); 4584} 4585 4586// disable social share 4587 4588function set_disable_social_share(checkbox) { 4589 ajax_request('/portal/set_disable_social_share?value=' + check_s(checkbox)); 4590} 4591 4592// suppress embed links 4593 4594function set_suppress_embed_links(checkbox) { 4595 ajax_request('/portal/set_suppress_embed_links?value=' + check_s(checkbox)); 4596} 4597 4598// wide screen support 4599 4600function set_wide_screen_support(checkbox) { 4601 window.location.href = '/portal/set_wide_screen_support?value=' + check_s(checkbox); 4602} 4603 4604// max user content width 4605 4606function set_max_user_content_width(select) { 4607 window.location.href = '/portal/set_max_user_content_width?value=' + select.options[select.selectedIndex].value; 4608} 4609 4610// thinner navigation 4611 4612function set_use_thinner_nav(checkbox) { 4613 window.location.href = '/portal/set_use_thinner_nav?value=' + check_s(checkbox); 4614} 4615 4616// dark mode 4617 4618function set_enable_dark_mode(checkbox) { 4619 window.location.href = '/portal/set_enable_dark_mode?value=' + check_s(checkbox); 4620} 4621 4622// mini-navigation 4623 4624function set_site_mini_nav(tab) { 4625 ajax_request('/portal/set_mini_nav?value=' + tab); 4626} 4627 4628// dropdown navigation 4629 4630function set_disable_dropdown_nav(checkbox) { 4631 ajax_request('/portal/set_disable_dropdown_nav?value=' + check_s(checkbox)); 4632} 4633 4634// tiles 4635 4636function set_show_tile_view_by_default(checkbox) { 4637 ajax_request('/portal/set_show_tile_view_by_default?value=' + check_s(checkbox)); 4638} 4639 4640// captcha 4641 4642function set_use_captcha(checkbox) { 4643 $.post('/portal/set_use_captcha?value=' + check_s(checkbox), function(){ 4644 location.reload(); 4645 }); 4646} 4647
4648function set_invisible_captcha(checkbox) { 4649 ajax_request('/portal/set_invisible_captcha?value=' + check_s(checkbox)); 4650} 4651 4652// lti_enabled 4653 4654function set_lti_enabled(checkbox) { 4655 $.post('/admin_lti/set_lti_enabled?value=' + check_s(checkbox), function(){ 4656 location.reload(); 4657 }); 4658} 4659 4660// lti_auto_enroll 4661 4662function set_lti_auto_enroll(checkbox) { 4663 ajax_request('/admin_lti/set_lti_auto_enroll?value=' + check_s(checkbox)); 4664} 4665 4666 4667// lti_auto_create 4668 4669function set_lti_auto_create(checkbox) { 4670 ajax_request('/admin_lti/set_lti_auto_create?value=' + check_s(checkbox)); 4671} 4672 4673// dst_event_recalculation 4674 4675function set_dst_event_recalculation(checkbox) { 4676 ajax_request('/portal/set_dst_event_recalculation?value=' + check_s(checkbox)); 4677 show_info('The calendar events are being recalculated. You will receive a message when the recalculation is complete.'); 4678} 4679 4680// portal type 4681 4682// TODO: could be done better 4683function set_portal_type(controller, value, id) { 4684 if (id == false) { 4685 window.location.href = '/' + controller + '/set_portal_type?value=' + value; 4686 } else { 4687 window.location.href = '/' + controller + '/set_portal_type/' + id + '?value=' + value; 4688 } 4689} 4690 4691// organization SSO 4692 4693function set_org_sso_policy(controller, value, id, sso_provider) { 4694 if (id == false) { 4695 window.location.href = '/' + controller + '/set_org_sso_policy?value=' + value + '&sso_provider=' + sso_provider; 4696 } else { 4697 window.location.href = '/' + controller + '/set_org_sso_policy/' + id + '?value=' + value + '&sso_provider=' + sso_provider; 4698 } 4699} 4700 4701// use accessible portal carousel 4702 4703function set_accessible_carousel(checkbox) { 4704 ajax_request('/portal/set_accessible_carousel?value=' + check_s(checkbox)); 4705} 4706 4707// use high contrast theme 4708 4709function set_high_contrast_theme(checkbox) { 4710 $.post('/portal/set_high_contrast_theme?value=' + check_s(checkbox), function(){ 4711 if (checkbox.checked) { 4712 $.post('/portal/set_allow_high_contrast_theme?value=false', function(){ 4713 location.reload(); 4714 }); 4715 } else { 4716 location.reload(); 4717 } 4718 }); 4719} 4720 4721function set_allow_high_contrast_theme(checkbox) { 4722 $.post('/portal/set_allow_high_contrast_theme?value=' + check_s(checkbox), function(){ 4723 location.reload(); 4724 }); 4725} 4726 4727// enable tile colors in new UI 4728 4729function set_enable_tile_colors_new_ui(checkbox) { 4730 ajax_request('/portal/set_enable_tile_colors_new_ui?value=' + check_s(checkbox)); 4731} 4732 4733// language 4734 4735function set_show_language_in_footer(checkbox) { 4736 window.location.href = '/portal/set_show_language_in_footer?value=' + check_s(checkbox); 4737} 4738 4739// new user interface 4740 4741function set_enable_new_ui(checkbox) { 4742 window.location.href = '/portal/set_enable_new_ui?value=' + check_s(checkbox); 4743} 4744 4745// super admin evo toggle 4746 4747function set_evo_enabled(checkbox) { 4748 window.location.href = '/portal/set_evo_enabled?value=' + check_s(checkbox); 4749} 4750 4751// evo enabled for account type 4752function set_evo_enabled_for_account_type(checkbox, account_type) { 4753 window.location.href = '/portal/set_evo_enabled_for_account_type?account_type=' + account_type + '&value=' + check_s(checkbox); 4754} 4755 4756// evo global super admin toggle 4757function set_evo_enabled_for_whole_portal(checkbox) { 4758 $.confirm({ 4759 content: $(checkbox).data('confirm'), 4760 confirm: function() { 4761 window.location.href = '/portal/set_evo_enabled_for_whole_portal?value=' + check_s(checkbox); 4762 }, 4763 cancel: function() { 4764 if ($(checkbox).is(":checked")) 4765 $(checkbox).prop( "checked", false ); 4766 else 4767 $(checkbox).prop( "checked", true ); 4768 } 4769 }); 4770} 4771 4772// ssl 4773 4774function set_ssl_support(checkbox) { 4775 window.location.href = '/portal/set_ssl_support?value=' + check_s(checkbox); 4776} 4777 4778// terminology 4779 4780function set_disable_plural_mapping(checkbox) { 4781 window.location.href = '/substitutions/set_disable_plural_mapping?value=' + check_s(checkbox); 4782} 4783 4784// home tabs 4785 4786function set_enable_top_tab(attribute, checkbox) { 4787 window.location.href = '/portal/set_enable_top_tab?attribute=' + attribute + '&value=' + check_s(checkbox); 4788} 4789 4790function set_landing_tab(value) { 4791 window.location.href = '/portal/set_landing_tab?value=' + value; 4792} 4793 4794// left bar 4795 4796function set_display_my_classes(checkbox) { 4797 window.location.href = '/portal/set_display_my_classes?value=' + check_s(checkbox); 4798} 4799 4800function set_display_my_paths(checkbox) { 4801 window.location.href = '/portal/set_display_my_paths?value=' + check_s(checkbox); 4802} 4803 4804function set_display_my_groups(checkbox) { 4805 window.location.href = '/portal/set_display_my_groups?value=' + check_s(checkbox); 4806} 4807 4808// simple login 4809 4810function set_simple_login(checkbox) { 4811 ajax_request('/configure_sso/set_simple_login?value=' + check_s(checkbox)); 4812} 4813 4814// password reset 4815 4816function set_password_reset(checkbox) { 4817 ajax_request('/configure_sso/set_password_reset?value=' + check_s(checkbox)); 4818} 4819 4820function toggle_auth0_custom_fields(){ 4821 if ($('#auth0_settings_auto_create').is(':checked') || $('#auth0_settings_auto_create_auth0_user').is(':checked')) { 4822 $('#auth0_custom_fields').show(); 4823 }else{ 4824 $('#auth0_custom_fields').hide(); 4825 } 4826} 4827 4828function set_auto_create_saml(checkbox){ 4829 if (check_s(checkbox) == 'true') { 4830 $('#saml_custom_fields').show(); 4831 $('#saml_account_field_matching').show(); 4832 }else{ 4833 $('#saml_custom_fields').hide(); 4834 $('#saml_account_field_matching').hide(); 4835 } 4836} 4837 4838function set_auto_create_auth0_user(checkbox){ 4839 if (check_s(checkbox) == 'true') { 4840 $('#email_verif').show(); 4841 }else{ 4842 $('#email_verif').hide(); 4843 } 4844} 4845 4846function set_auto_create_oauth2(checkbox){ 4847 if (check_s(checkbox) == 'true') { 4848 $('#oauth2_custom_fields').show(); 4849 }else{ 4850 $('#oauth2_custom_fields').hide(); 4851 } 4852} 4853 4854// UTM tags 4855 4856function set_store_utm_tags(checkbox) { 4857 ajax_request('/portal/set_store_utm_tags?value=' + check_s(checkbox)); 4858} 4859 4860// configure group 4861 4862function configure_group(attribute, group_id, checkbox) { 4863 ajax_request('/group_configure/set_attribute/' + group_id + '?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false')); 4864} 4865 4866function configure_group_top_tab(group_id, radio_button) { 4867 window.location.href = '/group_configure/set_top_tab/' + group_id + '?attribute=' + radio_button.value; 4868} 4869 4870function set_group_start_tab(item_id, checkbox) { 4871 window.location.href = '/group_configure/set_start_tab/' + item_id + '?attribute=' + checkbox.value + '&value=' + (checkbox.checked ? 'true' : 'false'); 4872} 4873 4874function set_group_announcement_comments(group_id, checkbox) { 4875 ajax_request('/group_configure/set_announcement_comments/' + group_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 4876} 4877 4878// configure organization 4879 4880function configure_organization(attribute, invert, org_id, checkbox) { 4881 var value = (invert ? !checkbox.checked : checkbox.checked); 4882 ajax_request('/organization/set_attribute/' + org_id + '?attribute=' + attribute + '&value=' + value); 4883} 4884 4885function configure_organization_with_refresh(attribute, invert, org_id, checkbox, from) { 4886 var value = (invert ? !checkbox.checked : checkbox.checked); 4887 window.location.href = '/organization/set_attribute_with_refresh/' + org_id + '?attribute=' + attribute + '&value=' + value + '&from=' + encodeURIComponent(from); 4888} 4889 4890// organizations 4891 4892function set_partition_organizations(checkbox) { 4893 window.location.href = '/organizations/set_partition_organizations?value=' + (checkbox.checked ? 'true' : 'false'); 4894} 4895 4896function set_cascading_admin_permissions(checkbox) { 4897 ajax_request('/organizations/set_cascading_admin_permissions?value=' + (checkbox.checked ? 'true' : 'false')); 4898} 4899 4900function set_cascading_manager_permissions(checkbox) { 4901 ajax_request('/organizations/set_cascading_manager_permissions?value=' + (checkbox.checked ? 'true' : 'false')); 4902} 4903 4904function set_allow_override_timeout_for_organizations(checkbox) { 4905 ajax_request('/organizations/set_allow_override_timeout_for_organizations?value=' + (checkbox.checked ? 'true' : 'false')); 4906} 4907 4908function set_custom_dashboard_for_all_sub_orgs(checkbox) { 4909 ajax_request('/organizations/set_custom_dashboard_for_all_sub_orgs?value=' + (checkbox.checked ? 'true' : 'false')); 4910} 4911 4912function set_allow_admin_multi_org_for_role(checkbox, role) { 4913 ajax_request('/organizations/set_allow_admin_multi_org_for_role?role=' + role + '&value=' + (checkbox.checked ? 'true' : 'false')); 4914} 4915 4916function set_missing_organization(dropdown) { 4917 ajax_request('/organizations/set_missing_organization?value=' + dropdown.value); 4918} 4919 4920function change_override_timeout_for_students(checkbox) { 4921 if(checkbox.checked) 4922 $('#override-students-timeout-container').show(); 4923 else 4924 $('#override-students-timeout-container').hide(); 4925} 4926 4927// portal tabs 4928 4929function set_profile_account_field(dropdown) { 4930 ajax_request('/profile_tabs/set_profile_account_field?value=' + dropdown.value); 4931} 4932 4933function set_profile_field_name(checkbox) { 4934 ajax_request('/profile_tabs/set_profile_field_name?value=' + (checkbox.checked ? 'true' : 'false')); 4935} 4936 4937// affiliate groups 4938 4939function configure_default_affiliate_group(group_id) { 4940 ajax_request('/affiliate_tiers/set_default?group_id=' + group_id); 4941} 4942 4943function assign_affiliate_group(element) { 4944 4945 var ids = []; 4946 $('#affiliates input[type="checkbox"]:checked').each(function(){ 4947 ids.push($(this).val()); 4948 }); 4949 4950 $.facebox({ 4951 'ajax' : $(element).attr('href') + '?ids=' + ids.join(',') 4952 }); 4953 4954 return false;
4955} 4956 4957// left bar 4958 4959function expand_online() { 4960 expand('online_bar'); 4961 ajax_request('/navigation/expand_online'); 4962} 4963 4964function collapse_online() { 4965 collapse('online_bar'); 4966 ajax_request('/navigation/collapse_online'); 4967} 4968 4969function expand_classes() { 4970 expand('classes_bar'); 4971 ajax_request('/navigation/expand_classes'); 4972} 4973 4974function collapse_classes() { 4975 collapse('classes_bar'); 4976 ajax_request('/navigation/collapse_classes'); 4977} 4978 4979function expand_groups() { 4980 expand('groups_bar'); 4981 ajax_request('/navigation/expand_groups'); 4982} 4983 4984function collapse_groups() { 4985 collapse('groups_bar'); 4986 ajax_request('/navigation/collapse_groups'); 4987} 4988 4989function expand_shortcuts() { 4990 expand('shortcuts_bar'); 4991 ajax_request('/navigation/expand_shortcuts'); 4992} 4993 4994function collapse_shortcuts() { 4995 collapse('shortcuts_bar'); 4996 ajax_request('/navigation/collapse_shortcuts'); 4997} 4998 4999// to-do list 5000 5001function over_todo(number) { 5002 set_style_element('todo_options' + number, { 5003 display : "inline-block" 5004 }); 5005} 5006 5007function out_todo(number) { 5008 hide_element('todo_options' + number); 5009} 5010 5011function delete_todo(number) { 5012 ajax_request('/task/destroy/' + number); 5013 fade_element('todo' + number); 5014} 5015 5016// publish student review 5017 5018function publish_student_review(class_id, review_id, checkbox) { 5019 ajax_request('/teacher_reviews/set_publish/' + class_id + '?review=' + review_id + '&value=' + (checkbox.checked ? 'true' : 'false')); 5020} 5021 5022// enable coupon 5023 5024function set_enable_coupon(coupon_id, checkbox) { 5025 ajax_request('/coupon/set_enabled/' + coupon_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 5026} 5027 5028// catalog calendar 5029 5030function set_catalog_calendar(checkbox) { 5031 ajax_request('/class_catalog_configure/set_catalog_calendar?value=' + (checkbox.checked ? 'true' : 'false')); 5032} 5033 5034// location filtering 5035 5036function set_catalog_location_filtering(checkbox) { 5037 ajax_request('/class_catalog_configure/set_catalog_location_filtering?value=' + (checkbox.checked ? 'true' : 'false')); 5038} 5039 5040// catalog search 5041 5042function set_catalog_search(checkbox) { 5043 ajax_request('/class_catalog_configure/set_catalog_search?value=' + (checkbox.checked ? 'true' : 'false')); 5044} 5045 5046function search_catalog(url) { 5047 var phrase = $('#catalog_search').val(); 5048 5049 if (url.indexOf('?') == -1) { 5050 window.location.href = url + "?phrase=" + phrase; 5051 } else { 5052 window.location.href = url + "&phrase=" + phrase; 5053 } 5054} 5055 5056function process_search_catalog(event, url) { 5057 if (event.keyCode == 13) { 5058 search_catalog(url); 5059 return false; 5060 } else { 5061 return true; 5062 } 5063} 5064 5065// search 5066 5067function submit_compact_search(url) { 5068 //var phrase = get_value('compact_search_phrase'); 5069 var phrase = $('.compact_search_phrase').last().val(); 5070 5071 if (url.indexOf('?') == -1) { 5072 window.location.href = url + "?phrase=" + phrase; 5073 } else { 5074 window.location.href = url + "&phrase=" + phrase; 5075 } 5076} 5077 5078function process_search(event, url) { 5079 if (event.keyCode == 13) { 5080 submit_compact_search(url); 5081 return false; 5082 } else { 5083 return true; 5084 } 5085} 5086 5087// gateway 5088 5089function update_lesson(select) { 5090 if (select.selectedIndex == 0) { 5091 hide_element('lesson_info'); 5092 } else { 5093 show_element('lesson_info'); 5094 } 5095} 5096 5097function update_gateway(select) { 5098 if (select.selectedIndex == 0) { 5099 hide_element('gateway'); 5100 } else { 5101 show_element('gateway'); 5102 } 5103} 5104 5105function update_threshold(checkbox) { 5106 if (checkbox.checked) { 5107 show_element('threshold'); 5108 } else { 5109 hide_element('threshold'); 5110 } 5111} 5112 5113// accounts misc options 5114 5115function set_enable_catalog_accounts(checkbox) { 5116 ajax_request('/accounts/set_enable_catalog_accounts?value=' + check_s(checkbox)); 5117} 5118 5119function set_default_to_school_address(checkbox) { 5120 ajax_request('/accounts/set_default_to_school_address?value=' + check_s(checkbox)); 5121} 5122 5123// grading 5124 5125function update_excused(checkbox) { 5126 if (checkbox.checked) { 5127 hide_element('score_area'); 5128 hide_element('edit_attachments'); 5129 hide_element('adjust_score'); 5130 hide_element('missing_area'); 5131 hide_element('absent_area'); 5132 hide_element('incomplete_area'); 5133 hide_element('rubric'); 5134 set_checked('excused', true); 5135 set_checked('absent', false); 5136 set_checked('missing', false); 5137 set_checked('incomplete', false); 5138 } else { 5139 show_element('score_area'); 5140 show_element('edit_attachments'); 5141 show_element('adjust_score'); 5142 show_element('missing_area'); 5143 show_element('absent_area'); 5144 show_element('incomplete_area'); 5145 show_element('rubric'); 5146 set_checked('excused', false); 5147 } 5148} 5149 5150function update_absent(checkbox) { 5151 if (checkbox.checked) {
5152 hide_element('score_area'); 5153 hide_element('edit_attachments'); 5154 hide_element('adjust_score'); 5155 hide_element('excused_area'); 5156 hide_element('missing_area'); 5157 hide_element('incomplete_area'); 5158 hide_element('rubric'); 5159 set_checked('excused', false); 5160 set_checked('absent', true); 5161 set_checked('missing', false); 5162 set_checked('incomplete', false); 5163 } else { 5164 show_element('score_area'); 5165 show_element('edit_attachments'); 5166 show_element('adjust_score'); 5167 show_element('excused_area'); 5168 show_element('missing_area'); 5169 show_element('incomplete_area'); 5170 show_element('rubric'); 5171 set_checked('absent', false); 5172 } 5173} 5174 5175function update_missing(checkbox) { 5176 if (checkbox.checked) { 5177 hide_element('score_area'); 5178 hide_element('edit_attachments'); 5179 hide_element('adjust_score'); 5180 hide_element('excused_area'); 5181 hide_element('absent_area'); 5182 hide_element('incomplete_area'); 5183 hide_element('rubric'); 5184 set_checked('excused', false); 5185 set_checked('absent', false); 5186 set_checked('missing', true); 5187 set_checked('incomplete', false); 5188 } else { 5189 show_element('score_area'); 5190 show_element('edit_attachments'); 5191 show_element('adjust_score'); 5192 show_element('excused_area'); 5193 show_element('absent_area'); 5194 show_element('incomplete_area'); 5195 show_element('rubric'); 5196 set_checked('missing', false); 5197 } 5198} 5199 5200function update_incomplete(checkbox) { 5201 if (checkbox.checked) { 5202 hide_element('score_area'); 5203 hide_element('edit_attachments'); 5204 hide_element('adjust_score'); 5205 hide_element('excused_area'); 5206 hide_element('absent_area'); 5207 hide_element('missing_area'); 5208 hide_element('rubric'); 5209 set_checked('excused', false); 5210 set_checked('absent', false); 5211 set_checked('missing', false); 5212 set_checked('incomplete', true); 5213 } else { 5214 show_element('score_area'); 5215 show_element('edit_attachments'); 5216 show_element('adjust_score'); 5217 show_element('excused_area'); 5218 show_element('absent_area'); 5219 show_element('missing_area'); 5220 show_element('rubric'); 5221 set_checked('incomplete', false); 5222 } 5223} 5224 5225// student comments 5226 5227function set_allow_student_comments(assignment_id, checkbox) { 5228 ajax_request('/teacher_freeform_assignment/set_allow_student_comments/' + assignment_id + '?value=' + check_s(checkbox)); 5229} 5230 5231// multiple choice 5232 5233function enable_feedback() { 5234 show_element('feedback'); 5235} 5236 5237function disable_feedback() { 5238 hide_element('feedback'); 5239} 5240 5241// freeform 5242 5243function enable_correct_answer() { 5244 show_element('correct_answer'); 5245} 5246 5247function disable_correct_answer() { 5248 hide_element('correct_answer'); 5249} 5250 5251// true/false 5252 5253var correct_answer = null; 5254 5255function set_correct_answer(value) { 5256 correct_answer = value; 5257 5258 if (value) { 5259 hide_element('correction'); 5260 } else if (correction_box) { 5261 show_element('correction'); 5262 } 5263} 5264 5265var correction_box = null; 5266 5267function set_correction_box(value) { 5268 correction_box = value; 5269 5270 if (value) { 5271 if (correct_answer == false) { 5272 show_element('correction'); 5273 } 5274 } else { 5275 hide_element('correction'); 5276 } 5277} 5278 5279function answered_false() { 5280 show_element('correction'); 5281} 5282 5283function answered_true() { 5284 hide_element('correction'); 5285 $('#correct_answer').val(''); 5286} 5287 5288// sections 5289 5290function set_assignment_given(checkbox, assignment_controller, assignment_id, from) { 5291 if (checkbox.checked) { 5292 window.location.href = '/' + assignment_controller + '/give/' + assignment_id + '?from=' + from; 5293 } else { 5294 window.location.href = '/' + assignment_controller + '/ungive/' + assignment_id + '?from=' + from; 5295 } 5296} 5297 5298function set_section_hidden(checkbox, class_id, lesson_id, section_id, is_assignment) { 5299 ajax_request('/teacher_section/' + ( is_assignment ? 'set_hidden_assignment/' : 'set_hidden/' ) + class_id + '?lesson_id=' + lesson_id + '§ion_id=' + section_id + '&value=' + check_s(checkbox)); 5300} 5301 5302// portal pages 5303 5304function set_portal_page_enabled(portal_page_id, checkbox, portal_id) { 5305 ajax_request('/portal_page/set_enabled?id=' + portal_page_id + '&portal_id=' + portal_id + '&value=' + check_s(checkbox)); 5306} 5307 5308// custom html 5309 5310function set_portal_custom_html_enabled(portal_custom_html_id, checkbox, portal_id) { 5311 window.location.href = '/portal_custom_htmls/set_enabled?id=' + portal_custom_html_id + '&value=' + check_s(checkbox); 5312} 5313 5314// profile pages 5315 5316function set_profile_tab_enabled(profile_tab_id, checkbox) { 5317 var n = $('input:checkbox[id^="profile_tab_"]:checked').length; 5318 5319 if (n > 0) { 5320 ajax_request('/profile_tab/set_enabled?id=' + profile_tab_id + '&value=' + check_s(checkbox)); 5321 } else { 5322 $('#' + checkbox.id).attr('checked', 'checked'); 5323 show_error('You cannot disable all User profile tabs. At least one should be enabled.'); 5324 } 5325} 5326 5327// portal slides 5328 5329function set_portal_slide_enabled(portal_slide_id, checkbox, portal_id) { 5330 ajax_request('/portal_slide/set_enabled?id=' + portal_slide_id + '&portal_id=' + portal_id + '&value=' + check_s(checkbox)); 5331} 5332 5333// portal icons 5334 5335function set_show_visitors(portal_icon_id, checkbox) { 5336 ajax_request('/portal_icon/set_show_visitors?id=' + portal_icon_id + '&value=' + check_s(checkbox)); 5337} 5338 5339function set_show_users(portal_icon_id, checkbox) {
5340 window.location.href = '/portal_icon/set_show_users?id=' + portal_icon_id + '&value=' + check_s(checkbox); 5341} 5342 5343// portal panels 5344 5345function set_portal_panel_enabled(portal_panel_id, checkbox, portal_id) { 5346 ajax_request('/portal_panel/set_enabled?id=' + portal_panel_id + '&portal_id=' + portal_id + '&value=' + check_s(checkbox)); 5347} 5348 5349// footers 5350 5351function set_footer_enabled(footer_id, checkbox) { 5352 window.location.href = '/footers/set_enabled?footer_id=' + footer_id + '&value=' + check_s(checkbox); 5353} 5354 5355// boxes 5356 5357function set_box_enabled(box_id, id, checkbox) { 5358 if (id == null) { 5359 ajax_request('/box/set_enabled?box_id=' + box_id + '&value=' + check_s(checkbox)); 5360 } else { 5361 ajax_request('/box/set_enabled/' + id + '?box_id=' + box_id + '&value=' + check_s(checkbox)); 5362 } 5363} 5364 5365function set_box_hideable(box_id, id, checkbox) { 5366 if (id == null) { 5367 ajax_request('/box/set_hideable?box_id=' + box_id + '&value=' + check_s(checkbox)); 5368 } else { 5369 ajax_request('/box/set_hideable/' + id + '?box_id=' + box_id + '&value=' + check_s(checkbox)); 5370 } 5371} 5372 5373// monitoring 5374 5375function set_monitoring(checkbox) { 5376 window.location.href = '/policies/set_monitoring?value=' + check_s(checkbox); 5377} 5378 5379function set_public_monitoring(checkbox) { 5380 ajax_request('/policies/set_public_monitoring?value=' + check_s(checkbox)); 5381} 5382 5383function set_announcement_comments(checkbox) { 5384 ajax_request('/policies/set_announcement_comments?value=' + check_s(checkbox)); 5385} 5386 5387function set_grade_synopsis(checkbox) { 5388 ajax_request('/policies/set_grade_synopsis?value=' + check_s(checkbox)); 5389} 5390 5391// email sync 5392 5393function email_sync(type) { 5394 ajax_request('/inbox/email_sync' + '?type=' + type); 5395} 5396 5397function sms_sync(type) { 5398 ajax_request('/inbox/sms_sync' + '?type=' + type); 5399} 5400 5401// teacher assignments 5402 5403function set_allow_late(controller, assignment_id, checkbox) { 5404 ajax_request('/' + controller + '/set_allow_late/' + assignment_id + '?value=' + check_s(checkbox)); 5405} 5406 5407function set_maximum_submissions(controller, assignment_id, dropdown) { 5408 ajax_request('/' + controller + '/set_maximum_submissions/' + assignment_id + '?value=' + dropdown.value); 5409} 5410 5411function override_allow_late(controller, assignment_id, student_id, checkbox) { 5412 ajax_request('/' + controller + '/override_allow_late/' + assignment_id + '?student=' + student_id + '&value=' + check_s(checkbox)); 5413} 5414 5415function override_maximum_submissions(controller, assignment_id, student_id, dropdown) { 5416 ajax_request('/' + controller + '/override_maximum_submissions/' + assignment_id + '?student=' + student_id + '&value=' + dropdown.value); 5417} 5418 5419// attachments 5420 5421function add_attachment(suffix, max, remove_string, the_width, custom) { 5422 var p = document.createElement("p"); 5423 5424 var line = document.createElement("input"); 5425 line.setAttribute("name", "attachments" + suffix + "[]"); 5426 line.setAttribute("type", "file"); 5427 line.setAttribute("class", "textInput"); 5428 5429 if (the_width != null) { 5430 if (custom) { 5431 line.setAttribute("style", "width: " + the_width + "px;float:left"); 5432 } else { 5433 line.setAttribute("style", "width: " + the_width + "px;"); 5434 } 5435 } 5436 5437 p.appendChild(line); 5438 5439 if (!custom) { 5440 var text1 = document.createTextNode(' ['); 5441 p.appendChild(text1); 5442 } 5443 5444 var a = document.createElement("a"); 5445 a.setAttribute("style", "cursor:pointer;"); 5446 5447 if (custom) { 5448 a.setAttribute("style", "cursor:pointer;float:right;margin-top:6px"); 5449 } 5450 5451 a.onclick = function(evt) { 5452 remove_attachment(this, suffix); 5453 }; 5454 5455 if (custom) { 5456 var text2 = document.createElement('i'); 5457 text2.setAttribute("class", "delete"); 5458 a.appendChild(text2); 5459 p.appendChild(a); 5460 } else { 5461 var text2 = document.createTextNode(remove_string); 5462 a.appendChild(text2); 5463 p.appendChild(a); 5464 } 5465 5466 if (!custom) { 5467 var text3 = document.createTextNode(']'); 5468 p.appendChild(text3); 5469 } 5470 5471 var element = document.getElementById("attachments" + suffix); 5472 element.appendChild(p); 5473 5474 var count = element.childNodes.length; 5475 5476 if (count == 1) { 5477 hide_element("add_attachment" + suffix + "_option"); 5478 } 5479 5480 if ((count < max) || (max == 0)) { 5481 show_element("add_another_attachment" + suffix + "_option"); 5482 } else {
5483 hide_element("add_another_attachment" + suffix + "_option"); 5484 } 5485} 5486 5487function remove_attachment(href, suffix) { 5488 var node = href.parentNode; 5489 node.parentNode.removeChild(node); 5490 5491 var element = document.getElementById("attachments" + suffix); 5492 var count = element.childNodes.length; 5493 5494 if (count == 0) { 5495 hide_element("add_another_attachment" + suffix + "_option"); 5496 show_element("add_attachment" + suffix + "_option"); 5497 } else { 5498 show_element("add_another_attachment" + suffix + "_option"); 5499 } 5500} 5501 5502// original assignment instructions 5503 5504function pop_up_assignment_instructions(controller, id) { 5505 if(is_mobile_app_mode()){ 5506 window.parent.postMessage("{\"method\": \"loadBrowser\", \"href\": \"" + '/' + controller + '/instructions/' + id + "\"}", "*"); 5507 }else{ 5508 window.open('/' + controller + '/instructions/' + id, 'instructions', 'height=560px,width=500px,toolbar=yes,directories=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,modal=no'); 5509 } 5510} 5511 5512// correct answer for freeform assignments 5513 5514function pop_up_correct_answer(controller, id) { 5515 if(is_mobile_app_mode()){ 5516 window.parent.postMessage("{\"method\": \"loadBrowser\", \"href\": \"" + '/' + controller + '/correct_answer/' + id + "\"}", "*"); 5517 }else { 5518 window.open('/' + controller + '/correct_answer/' + id, 'correctanswer', 'height=560px,width=500px,toolbar=yes,directories=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,modal=no'); 5519 } 5520} 5521 5522// account field 5523 5524function pop_up_field(user_id, field_id) { 5525 if(is_mobile_app_mode()){ 5526 window.parent.postMessage("{\"method\": \"loadBrowser\", \"href\": \"" + '/user/field/' + user_id + '?field=' + field_id + "\"}", "*"); 5527 }else { 5528 window.open('/user/field/' + user_id + '?field=' + field_id, 'field', 'height=560px,width=500px,toolbar=yes,directories=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,modal=no'); 5529 } 5530} 5531 5532// changes 5533 5534function toggle_child(checkbox, child_id) { 5535 if (checkbox.checked) { 5536 select_all_checkboxes('child_' + child_id); 5537 } else { 5538 clear_all_checkboxes('child_' + child_id); 5539 } 5540} 5541 5542function toggle_common_changes(checkbox) { 5543 if (checkbox.checked) { 5544 select_all_checkboxes_by_id('common_'); 5545 } else { 5546 clear_all_checkboxes_by_id('common_'); 5547 } 5548} 5549 5550function toggle_common_change(checkbox, count) { 5551 if (checkbox.checked) { 5552 select_all_checkboxes_by_id('common_' + count); 5553 } else { 5554 clear_all_checkboxes_by_id('common_' + count); 5555 } 5556} 5557 5558function select_all_checkboxes(prefix) { 5559 var checkboxes = $('input:checkbox[name^=' + prefix + ']'); 5560 5561 for (var i = 0; i < checkboxes.length; i++) { 5562 checkboxes[i].checked = true; 5563 } 5564} 5565 5566function clear_all_checkboxes(prefix) { 5567 var checkboxes = $('input:checkbox[name^=' + prefix + ']'); 5568 5569 for (var i = 0; i < checkboxes.length; i++) { 5570 checkboxes[i].checked = false; 5571 } 5572} 5573 5574function select_all_checkboxes_by_id(prefix) { 5575 var checkboxes = $('input:checkbox[id^=' + prefix + ']'); 5576 5577 for (var i = 0; i < checkboxes.length; i++) { 5578 checkboxes[i].checked = true; 5579 } 5580} 5581 5582function clear_all_checkboxes_by_id(prefix) { 5583 var checkboxes = $('input:checkbox[id^=' + prefix + ']'); 5584 5585 for (var i = 0; i < checkboxes.length; i++) { 5586 checkboxes[i].checked = false; 5587 } 5588} 5589 5590function toggle_all_teams(checkbox) { 5591 if (checkbox.checked) { 5592 var checkboxes = $('input:checkbox[name^="teams[]"]'); 5593 5594 for (var i = 0; i < checkboxes.length; i++) { 5595 checkboxes[i].checked = true; 5596 } 5597 } else { 5598 var checkboxes = $('input:checkbox[name^="teams[]"]'); 5599 5600 for (var i = 0; i < checkboxes.length; i++) { 5601 checkboxes[i].checked = false; 5602 } 5603 } 5604} 5605 5606// edit_state 5607 5608function update_state(select, name) { 5609 var country = select.options[select.selectedIndex].value; 5610 5611 if (country == 'United States' || country == 'Brazil') { 5612 show_element(name + '_state_div'); 5613 hide_element(name + '_other_state_div'); 5614 $.get('/account_fields/get_states_for_country?value='+ country, function(data) { 5615 $('select#' + name + '_state').empty(); 5616 $.each(data.names, function (index, state) { 5617 $('select#' + name + '_state').append('<option value="'+state.code+'">'+state.name+'</option>'); 5618 }); 5619 }); 5620 $('select#' + name + '_state').attr('disabled', false); 5621 $('input#' + name + '_other_state').attr('disabled', true); 5622 } else {
5623 hide_element(name + '_state_div'); 5624 show_element(name + '_other_state_div'); 5625 $('select#' + name + '_state').attr('disabled', true); 5626 $('input#' + name + '_other_state').attr('disabled', false); 5627 } 5628} 5629 5630// district policies 5631 5632function set_district_policy(attribute, invert, checkbox) { 5633 var value = ( invert ? !checkbox.checked : checkbox.checked); 5634 ajax_request('/policies/set_district_attribute?attribute=' + attribute + '&value=' + (value == true ? 'true' : 'false')); 5635} 5636 5637// lesson 5638 5639function update_all_day_lesson(checkbox) { 5640 if (checkbox.checked) { 5641 show_element('all_day'); 5642 hide_element('not_all_day'); 5643 hide_element('duration'); 5644 } else { 5645 show_element('not_all_day'); 5646 hide_element('all_day'); 5647 show_element('duration'); 5648 } 5649} 5650 5651// event 5652 5653function update_all_day(checkbox) { 5654 if (checkbox.checked) { 5655 show_element('all_day'); 5656 hide_element('not_all_day'); 5657 set_checked('is_conference', false); 5658 } else { 5659 show_element('not_all_day'); 5660 hide_element('all_day'); 5661 } 5662} 5663 5664// recurring event 5665 5666function update_recurring(checkbox, is_zoomus) { 5667 if (checkbox.checked) { 5668 show_element('recurring'); 5669 hide_element('based_on_week'); 5670 $("#is_weekly_based").prop( "checked", false ); 5671 hide_element('event_rsvp'); 5672 set_checked('event_rsvp', false); 5673 hide_element('event_rsvp_label'); 5674 if(!is_zoomus) { 5675 hide_element('is_conference'); 5676 set_checked('is_conference', false); 5677 hide_element('event_conference_label'); 5678 } 5679 if(get_value('event_repeats') == "Monthly"){ 5680 show_element('is_weekly_based'); 5681 show_element('is_weekly_based_label'); 5682 } 5683 } else { 5684 show_element('event_rsvp'); 5685 show_element('event_rsvp_label'); 5686 hide_element('is_weekly_based'); 5687 hide_element('is_weekly_based_label'); 5688 $("#is_weekly_based").prop( "checked", false ); 5689 show_element('based_on_week'); 5690 hide_element('recurring'); 5691 if(!is_zoomus) { 5692 show_element('is_conference'); 5693 show_element('event_conference_label') 5694 } 5695 } 5696} 5697 5698function update_rsvp_field(checkbox) { 5699 if (checkbox.checked) { 5700 hide_element('event_recurring'); 5701 hide_element('event_recurring_label'); 5702 } else { 5703 show_element('event_recurring'); 5704 show_element('event_recurring_label'); 5705 } 5706} 5707 5708function update_weekly_based(checkbox) { 5709 if (checkbox.checked) { 5710 show_element('based_on_week'); 5711 } else { 5712 hide_element('based_on_week'); 5713 } 5714} 5715 5716// ends none 5717 5718function update_ends_none(radio_button) { 5719 if (radio_button.checked) { 5720 hide_element('ends_on'); 5721 hide_element('ends_after'); 5722 hide_element('after_occurrences'); 5723 } 5724} 5725 5726// ends after 5727 5728function update_ends_after(radio_button) { 5729 if (radio_button.checked) { 5730 hide_element('ends_on'); 5731 show_element('after_occurrences'); 5732 $('#event_ends_occurrences').width( 60 ); 5733 show_element('ends_after'); 5734 } 5735} 5736 5737// ends on 5738 5739function update_ends_at(radio_button) { 5740 if (radio_button.checked) { 5741 show_element('ends_on'); 5742 hide_element('ends_after'); 5743 hide_element('after_occurrences'); 5744 } 5745} 5746 5747function get_repeats_value(){ 5748 $('#event_repeats').width( 80 ); 5749 $('#event_repeat_every').width( 60 ); 5750 $('#event_ends_occurrences').width( 60 ); 5751 var e = document.getElementById("event_repeats"); 5752 var repeats = e.options[e.selectedIndex].text; 5753 set_repeats_options(repeats); 5754} 5755 5756// repeats options 5757 5758function set_repeats_options(dropdown){ 5759 if(dropdown == 'Daily'){ 5760 show_element('repeats_every_days'); 5761 hide_element('repeats_every_weeks'); 5762 hide_element('repeats_every_months'); 5763 hide_element('repeats_every_years'); 5764 hide_element('weekly_based'); 5765 hide_element('is_weekly_based'); 5766 hide_element('is_weekly_based_label'); 5767 $("#is_weekly_based").prop( "checked", false ); 5768 hide_element('based_on_week'); 5769 }else if(dropdown == 'Weekly'){ 5770 show_element('repeats_every_weeks'); 5771 hide_element('repeats_every_days'); 5772 hide_element('repeats_every_months'); 5773 hide_element('repeats_every_years'); 5774 hide_element('weekly_based'); 5775 hide_element('is_weekly_based'); 5776 hide_element('is_weekly_based_label'); 5777 $("#is_weekly_based").prop( "checked", false );
5778 hide_element('based_on_week'); 5779 }else if(dropdown == 'Monthly'){ 5780 hide_element('repeats_every_days'); 5781 hide_element('repeats_every_weeks'); 5782 show_element('repeats_every_months'); 5783 hide_element('repeats_every_years'); 5784 show_element('weekly_based'); 5785 show_element('is_weekly_based'); 5786 show_element('is_weekly_based_label'); 5787 }else if(dropdown == 'Yearly'){ 5788 hide_element('repeats_every_days'); 5789 hide_element('repeats_every_weeks'); 5790 hide_element('repeats_every_months'); 5791 show_element('repeats_every_years'); 5792 hide_element('weekly_based'); 5793 hide_element('is_weekly_based'); 5794 hide_element('is_weekly_based_label'); 5795 $("#is_weekly_based").prop( "checked", false ); 5796 hide_element('based_on_week'); 5797 } 5798} 5799 5800// repeats scheduled reports 5801 5802function get_repeats_value_scheduled_reports(){ 5803 $('#report_id').width( 480 ); 5804 $('#repeats').width( 90 ); 5805 $('#repeat_every').width( 50 ); 5806 var e = document.getElementById("repeats"); 5807 var repeats = e.options[e.selectedIndex].text; 5808 set_repeats_scheduled_reports(repeats); 5809} 5810 5811function set_repeats_scheduled_reports(dropdown){ 5812 if(dropdown == 'Minutely') { 5813 show_element('repeats_every_minutes'); 5814 hide_element('repeats_every_days'); 5815 hide_element('repeats_every_weeks'); 5816 hide_element('repeats_every_months'); 5817 hide_element('repeats_every_years'); 5818 }else if(dropdown == 'Daily'){ 5819 hide_element('repeats_every_minutes'); 5820 show_element('repeats_every_days'); 5821 hide_element('repeats_every_weeks'); 5822 hide_element('repeats_every_months'); 5823 hide_element('repeats_every_years'); 5824 }else if(dropdown == 'Weekly'){ 5825 hide_element('repeats_every_minutes'); 5826 show_element('repeats_every_weeks'); 5827 hide_element('repeats_every_days'); 5828 hide_element('repeats_every_months'); 5829 hide_element('repeats_every_years'); 5830 }else if(dropdown == 'Monthly'){ 5831 hide_element('repeats_every_minutes'); 5832 hide_element('repeats_every_days'); 5833 hide_element('repeats_every_weeks'); 5834 show_element('repeats_every_months'); 5835 hide_element('repeats_every_years'); 5836 }else if(dropdown == 'Yearly'){ 5837 hide_element('repeats_every_minutes'); 5838 hide_element('repeats_every_days'); 5839 hide_element('repeats_every_weeks'); 5840 hide_element('repeats_every_months'); 5841 show_element('repeats_every_years'); 5842 } 5843} 5844 5845function update_repeats_schedule_job(checkbox) { 5846 if (checkbox.checked) { 5847 show_element('repeats_job'); 5848 } else { 5849 hide_element('repeats_job'); 5850 } 5851} 5852 5853// reports new popup 5854 5855// period type 5856 5857function update_period_type_range(radio_button) { 5858 if (radio_button.checked) { 5859 hide_element('period_type_last'); 5860 hide_element('period_type_current'); 5861 show_element('period_type_range'); 5862 } 5863} 5864 5865function update_period_type_last(radio_button) { 5866 if (radio_button.checked) { 5867 show_element('period_type_last'); 5868 hide_element('period_type_current'); 5869 hide_element('period_type_range'); 5870 } 5871} 5872 5873function update_period_type_current(radio_button) { 5874 if (radio_button.checked) { 5875 hide_element('period_type_last'); 5876 show_element('period_type_current'); 5877 hide_element('period_type_range'); 5878 } 5879} 5880 5881// my reports 5882 5883function set_my_report(report_id, checkbox, is_my_catalog) { 5884 ajax_request('/reports/set_my_report?report_id=' + report_id + '&value=' + (checkbox.checked ? 'true' : 'false')); 5885 5886 if (!checkbox.checked && is_my_catalog) { 5887 $("div#report_" + report_id).remove(); 5888 } 5889} 5890 5891// web conferencing on-click processing 5892 5893function common_checked_conference_gateway(supports_recurring = false) { 5894 set_checked('event_all_day', false); 5895 $("#event_all_day").prop( "checked", false ); 5896 show_element('not_all_day'); 5897 hide_element('all_day'); 5898 if(!supports_recurring){ 5899 hide_element('event_recurring'); 5900 hide_element('event_recurring_label'); 5901 } 5902} 5903 5904function common_unchecked_conference_gateway(supports_recurring = false) { 5905 $('#event_form button[type="submit"]').off('click'); 5906 if(!supports_recurring){ 5907 show_element('event_recurring'); 5908 show_element('event_recurring_label'); 5909 } 5910} 5911 5912function process_onclick_web_conferencing(checkbox, no_token, auth_url, client_name, pop_params, supports_recurring = false) { 5913 if (checkbox.checked) { 5914 common_checked_conference_gateway(supports_recurring); 5915 5916 if (no_token) { 5917 if(is_mobile_app_mode()){ 5918 window.parent.postMessage("{\"method\": \"loadBrowser\", \"href\": \"'" + auth_url + "\"}", "*"); 5919 }else{ 5920 var conferencing_window = window.open("", "conferencingWindow"); 5921 if(!(typeof conferencing_window === 'undefined' || conferencing_window === null)) { 5922 conferencing_window.close(); 5923 } 5924 window.open(auth_url, 'conferencingWindow', pop_params); 5925 } 5926 } 5927 5928 $('#event_form button[type="submit"]').click(function() { 5929 $('#conference_status').html('<p>Communicating with ' + client_name + '... <img style="margin-left:10px" src="/images/loading-16.gif" /></p>').show(); 5930 }); 5931 } else { 5932 common_unchecked_conference_gateway(supports_recurring); 5933 } 5934} 5935 5936// report 5937 5938function update_current_month(checkbox) { 5939 if (checkbox.checked) { 5940 show_element('organizations_option');
5941 hide_element('output_option'); 5942 } else { 5943 hide_element('organizations_option'); 5944 show_element('output_option'); 5945 } 5946} 5947 5948// grade 5949 5950function update_adjust(checkbox) { 5951 if (checkbox.checked) { 5952 show_element('adjust'); 5953 } else { 5954 hide_element('adjust'); 5955 } 5956} 5957 5958function update_adjust_link(el) { 5959 if ($('#adjust').is(':visible')) { 5960 $(el).parent().find('input[name="adjustment[enable]"]').val(false); 5961 } else { 5962 $(el).parent().find('input[name="adjustment[enable]"]').val(true); 5963 } 5964 5965 $('#adjust').toggle(); 5966} 5967 5968// groups 5969 5970function show_public() { 5971 show_element('public'); 5972 hide_element('private'); 5973} 5974 5975function show_private() { 5976 show_element('private'); 5977 hide_element('public'); 5978} 5979 5980// lessons 5981 5982function set_current_lesson_tile() { 5983 var checked_lesson_ids = []; 5984 5985 $('#lessons input:checkbox').each(function () { 5986 if (this.checked) { 5987 var lesson_id; 5988 5989 if (this.value.indexOf('check_') !== -1) 5990 lesson_id = this.value.substring(6); // present in the row view 5991 else 5992 lesson_id = this.value; // tile view 5993 5994 checked_lesson_ids.push(lesson_id); 5995 } 5996 }); 5997 5998 // TODO: translate 5999 if (checked_lesson_ids.length == 0) { 6000 $.alert({content: 'Please select one lesson to make current'}); 6001 } else if (checked_lesson_ids.length > 1) { 6002 $.alert({content: 'You have selected more than one lesson, but you can only make one lesson current'}); 6003 } else { 6004 var lesson_id = checked_lesson_ids[0]; 6005 6006 if (current_lesson_id == lesson_id) { 6007 current_lesson_id = null; 6008 6009 $.get('/teacher_lessons/clear_current/' + class_id, function () { 6010 window.location.reload(); 6011 }); 6012 } else { 6013 current_lesson_id = lesson_id; 6014 6015 $.get('/teacher_lessons/set_current/' + class_id + '?lesson_id=' + lesson_id, function () { 6016 window.location.reload(); 6017 }); 6018 } 6019 } 6020} 6021 6022// TODO: this one isn't even used. But it's quite nice since it doesn't redraw. Perhaps use it instead? 6023 6024function set_current_lesson_row() { 6025 var checked_lessons = []; 6026 var lesson_position = 1; 6027 $('.instructor_module_view input:checkbox').each(function(){ 6028 if(this.checked){ 6029 checked_lessons.push(lesson_position); 6030 } 6031 lesson_position++; 6032 }); 6033 if(checked_lessons.length == 0){ 6034 $.alert({content: 'Please select one lesson to make current'}); 6035 }else if(checked_lessons.length > 1){ 6036 $.alert({content: 'You have selected more than one lesson, but you can only make one lesson current'}); 6037 }else{ 6038 var position = checked_lessons[0]; 6039 $('.instructor_module_view .imgCrop .current').addClass('hide'); 6040 $('.instructor_module_view > table:nth-of-type(' + position + ') .imgCrop .current').removeClass('hide'); 6041 6042 if (current_lesson == position) { 6043 current_lesson = null; 6044 $.get('/teacher_lessons/clear_current/' + class_id, function(){ 6045 $('.instructor_module_view > table:nth-of-type(' + position + ') .imgCrop .current').addClass('hide'); 6046 //window.location.reload(); 6047 }); 6048 } else { 6049 current_lesson = position; 6050 $.get('/teacher_lessons/set_current/' + class_id + '?position=' + position, function(){ 6051 //window.location.reload(); 6052 }); 6053 } 6054 } 6055} 6056 6057// launch SCORM 6058 6059function launch_scorm(url, title, height, width) { 6060 window.open(url, 'SCORM', 'height=' + height + ',width=' + width + ',toolbar=no,directories=no,location=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,modal=no'); 6061} 6062 6063function refreshScormNavigation(type){ 6064 if ($('#'+type+'_launch_mode_always').is(':checked')) { 6065 $('#set_navigation').hide(); 6066 } else { 6067 $('#set_navigation').show(); 6068 } 6069} 6070 6071// configure quiz 6072 6073function init_quiz_configure(the_controller, the_id) { 6074 configure_controller = the_controller; 6075 configure_id = the_id; 6076} 6077 6078// school policies 6079 6080function set_walled_community(checkbox) { 6081 ajax_request('/policies/set_walled_community?value=' + check_s(checkbox)); 6082} 6083 6084function set_attribute(attribute, invert, checkbox, confirm_on_true, confirm_on_false) { 6085 var value = (invert ? !checkbox.checked : checkbox.checked); 6086 var confirm = (value && confirm_on_true) || (!value && confirm_on_false); 6087 var uncheck = function () { 6088 $(checkbox).prop("checked", !$(checkbox).prop("checked")); 6089 }; 6090 6091 var ajaxCall = function() { 6092 var url = '/policies/set_attribute?attribute=' + attribute + '&value=' + (value == true ? 'true' : 'false'); 6093 6094 $.ajax({ 6095 url: url, 6096 method: 'post', 6097 dataType: 'json', 6098 success: function(data) { 6099 if(data && data.info ) { 6100 show_warning( data.info ); 6101 uncheck(); 6102 } 6103 } 6104 }); 6105 }; 6106 6107 if( confirm ) 6108 $.confirm({ content: confirm, confirm: ajaxCall, cancel: uncheck }); 6109 else 6110 ajaxCall(); 6111} 6112 6113function set_attribute_with_refresh(attribute, invert, checkbox, from) { 6114 var value = (invert ? !checkbox.checked : checkbox.checked); 6115 window.location.href = '/policies/set_attribute_with_refresh?attribute=' + attribute + '&value=' + (value == true ? 'true' : 'false') + '&from=' + encodeURIComponent(from); 6116} 6117 6118function set_organization_cascade_settings(organization_id, checkbox) { 6119 var value = checkbox.checked; 6120 6121 var url = '/organization_visitor_portal/set_cascade_settings/' + organization_id + '?value=' + (value == true ? 'true' : 'false'); 6122 ajax_request(url); 6123} 6124 6125function set_organization_inherit_school_conferencing_configuration(organization_id, checkbox) { 6126 var value = checkbox.checked; 6127 6128 var url = '/organization_conferencing/set_inherit_school_configuration/' + organization_id + '?value=' + (value == true ? 'true' : 'false'); 6129 $.ajax({ url : url, type : 'POST', success: function() { window.location.reload(); } }); 6130} 6131 6132function set_organization_gateway_config(organization_id, gateway_type, mode, radio) { 6133 var url = '/organization_conferencing/set_gateway_config/' + organization_id + '?gateway_type=' + gateway_type + '&mode=' + mode; 6134 $.ajax({ 6135 url: url, 6136 type: 'POST', 6137 success: function() { window.location.reload(); } 6138 }); 6139} 6140 6141function set_organization_conferencing_cascade_settings(organization_id, checkbox) { 6142 var value = checkbox.checked; 6143 6144 var url = '/organization_conferencing/set_cascade_settings/' + organization_id + '?value=' + (value == true ? 'true' : 'false'); 6145 ajax_request(url); 6146} 6147 6148function set_organization_inherit_school_payment_gateway_configuration(organization_id, checkbox) { 6149 var value = checkbox.checked; 6150 6151 var url = '/organization_ecommerce/set_inherit_school_payment_gateway_configuration/' + organization_id + '?value=' + (value == true ? 'true' : 'false'); 6152 $.ajax({ url : url, type : 'POST', success: function() { window.location.reload(); } }); 6153} 6154 6155function set_organization_payment_gateway_cascade_settings(organization_id, checkbox) { 6156 var value = checkbox.checked; 6157 6158 var url = '/organization_ecommerce/set_payment_gateway_cascade_settings/' + organization_id + '?value=' + (value == true ? 'true' : 'false'); 6159 ajax_request(url); 6160} 6161 6162/* roles */ 6163 6164function set_role_enabled(role_id, checkbox) { 6165 var value = checkbox.checked; 6166 window.location.href = '/roles/set_enabled?role_id=' + role_id + '&value=' + checkbox.checked; 6167} 6168 6169function set_avatar_attribute(attribute, invert, checkbox, refresh) { 6170 var value = (invert ? !checkbox.checked : checkbox.checked); 6171 6172 if (refresh) { 6173 ajax_request('/avatars/set_attribute?attribute=' + attribute + '&value=' + (value == true ? 'true' : 'false'), {asynchronous : false}); 6174 window.location.href = '/avatars'; 6175 } else { 6176 ajax_request('/avatars/set_attribute?attribute=' + attribute + '&value=' + (value == true ? 'true' : 'false')); 6177 } 6178} 6179 6180function set_zapier_attribute(field) { 6181 var values = []; 6182 6183 $('input[name^="zapier_events"]').each(function(){ 6184 if($(this).is(':checked')){ 6185 values.push($(this).attr('id').replace('zapier_events_', '')); 6186 } 6187 }); 6188 6189 ajax_request('/zapier_configure/set_attribute?value=' + values.join(',')); 6190} 6191 6192function set_level_display(dropdown) { 6193 ajax_request('/policies/set_level_display?value=' + dropdown.value); 6194} 6195 6196function set_agent_setting(attribute, invert, checkbox, refresh, class_id) { 6197 var value = (invert ? !checkbox.checked : checkbox.checked); 6198 6199 if (refresh) { 6200 ajax_request('/class_configure/set_agent_attribute/' + class_id + '?attribute=' + attribute + '&value=' + (value == true ? 'true' : 'false'), {asynchronous : false}); 6201 window.location.href = '/class_configure/agent/' + class_id; 6202 } else { 6203 ajax_request('/class_configure/set_agent_attribute/' + class_id + '?attribute=' + attribute + '&value=' + (value == true ? 'true' : 'false')); 6204 } 6205} 6206 6207/* two factor authentication */ 6208 6209function toggle_require_2fa_for_role(role, checkbox) { 6210 ajax_request('/two_factor_auth/require_for_role?role=' + role + '&value=' + (checkbox.checked ? 'true' : 'false')); 6211} 6212 6213function set_timeout_for_2fa(dropdown) { 6214 ajax_request('/two_factor_auth/set_timeout?value=' + dropdown.value); 6215} 6216 6217function set_enforce_2fa_days(dropdown) { 6218 ajax_request('/two_factor_auth/set_enforce_days?value=' + dropdown.value); 6219} 6220 6221function set_remind_2fa_days(dropdown) { 6222 ajax_request('/two_factor_auth/set_remind_days?value=' + dropdown.value); 6223} 6224 6225// ecommerce 6226 6227function set_ecommerce_attribute(attribute, checkbox) { 6228 ajax_request('/ecommerce/set_attribute?attribute=' + attribute + '&value=' + (checkbox.checked == true ? 'true' : 'false')); 6229} 6230 6231function set_toggle_tax_code(checkbox, tax_code) { 6232 $('.tax_code').attr('disabled', true); 6233 window.location.href = '/tax_codes/set_enable_tax_code?tax_code=' + tax_code + '&value=' + (checkbox.checked ? 'true' : 'false'); 6234} 6235
6236function set_cc_processing_gateway(school_id, radio_button) { 6237 ajax_request('/payment_gateways/set_credit_card_processor_gateway?payment_gateway_id=' + radio_button.value); 6238} 6239 6240function set_enable_payment_gateway(payment_gateway_id, checkbox, user_subscriptions_count) { 6241 if ((!checkbox.checked) && (user_subscriptions_count > 0)) { 6242 prompt = "Please note that there are "+ user_subscriptions_count + " active subscriptions created with this payment gateway. By disabling this gateway, all subscriptions will be cancelled. Are you sure you want to proceed?"; 6243 $.confirm({ 6244 content: prompt, 6245 confirm: function() { 6246 ajax_request('/payment_gateways/set_enable_payment_gateway?payment_gateway_id=' + payment_gateway_id + '&value=' + 'false'); 6247 }, 6248 cancel: function() { 6249 checkbox.checked = true; 6250 } 6251 }); 6252 } else { 6253 ajax_request('/payment_gateways/set_enable_payment_gateway?payment_gateway_id=' + payment_gateway_id + '&value=' + (checkbox.checked ? 'true' : 'false')); 6254 } 6255} 6256 6257function set_lock_payment_gateway(payment_gateway_id, checkbox) { 6258 prompt = "Are you sure you want to proceed?"; 6259 $.confirm({ 6260 content: prompt, 6261 confirm: function() { 6262 url = '/payment_gateways/set_lock_payment_gateway?payment_gateway_id=' + payment_gateway_id + '&value=' + (checkbox.checked ? 'true' : 'false'); 6263 $.get(url, function(response) { $('#edit_td_' + payment_gateway_id).html(response.edit_td); }); 6264 }, 6265 cancel: function() { 6266 checkbox.checked = !checkbox.checked; 6267 } 6268 }); 6269} 6270 6271function set_organization_cc_processing_gateway(organization_id, radio_button) { 6272 ajax_request('/organization_payment_gateways/set_credit_card_processor_gateway?payment_gateway_id=' + radio_button.value + '&organization_id=' + organization_id); 6273} 6274 6275function set_organization_enable_payment_gateway(payment_gateway_id, checkbox, user_subscriptions_count, organization_id) { 6276 if ((!checkbox.checked) && (user_subscriptions_count > 0)) { 6277 prompt = "Please note that there are "+ user_subscriptions_count + " active subscriptions created with this payment gateway. By disabling this gateway, all subscriptions will be cancelled. Are you sure you want to proceed?"; 6278 $.confirm({ 6279 content: prompt, 6280 confirm: function() { 6281 ajax_request('/organization_payment_gateways/set_enable_payment_gateway?payment_gateway_id=' + payment_gateway_id + '&value=' + 'false' + '&organization_id=' + organization_id); 6282 }, 6283 cancel: function() { 6284 checkbox.checked = true; 6285 } 6286 }); 6287 } else { 6288 ajax_request('/organization_payment_gateways/set_enable_payment_gateway?payment_gateway_id=' + payment_gateway_id + '&value=' + (checkbox.checked ? 'true' : 'false') + '&organization_id=' + organization_id); 6289 } 6290} 6291 6292function set_organization_lock_payment_gateway(payment_gateway_id, checkbox, organization_id) { 6293 prompt = "Are you sure you want to proceed?"; 6294 $.confirm({ 6295 content: prompt, 6296 confirm: function() { 6297 url = '/organization_payment_gateways/set_lock_payment_gateway?payment_gateway_id=' + payment_gateway_id + '&value=' + (checkbox.checked ? 'true' : 'false') + '&organization_id=' + organization_id; 6298 $.get(url, function(response) { $('#edit_td_' + payment_gateway_id).html(response.edit_td); }); 6299 }, 6300 cancel: function() { 6301 checkbox.checked = !checkbox.checked; 6302 } 6303 }); 6304} 6305 6306// catalog 6307 6308function set_catalog_format(dropdown) { 6309 ajax_request('/class_catalogs_configure/set_format?value=' + dropdown.value); 6310} 6311 6312function set_category_ordering(dropdown, from) { 6313 ajax_request('/class_catalogs_configure/set_category_ordering?value=' + dropdown.value); 6314} 6315 6316function set_class_ordering(dropdown) { 6317 ajax_request('/class_catalogs_configure/set_class_ordering?value=' + dropdown.value); 6318} 6319function set_default_organization(dropdown, org_id) { 6320 var new_id = $(dropdown).val(); 6321 $(document.querySelectorAll('[id ^= "resource_'+org_id+'"]')).each(function(){ 6322 $(this).val(new_id); 6323 }); 6324 6325 set_proceed_to_move_submit_btn(); 6326} 6327 6328function set_main_default_organization(org_id) { 6329 var arr = $(document.querySelectorAll('[id ^= "resource_'+org_id+'"]')).map(function() { return $(this).val(); }).get(); 6330 arr.shift(); 6331 var uniqueNames = []; 6332 $.each(arr, function(i, el){ 6333 if($.inArray(el, uniqueNames) === -1) uniqueNames.push(el); 6334 }); 6335 6336 if(uniqueNames.length > 1) { 6337 $("#resource_"+org_id+"_all_organizations_id").val('--'); 6338 } else { 6339 $("#resource_"+org_id+"_all_organizations_id").val(uniqueNames[0]); 6340 } 6341 6342 set_proceed_to_move_submit_btn(); 6343} 6344 6345function set_proceed_to_move_submit_btn() { 6346 var arr = $(document.querySelectorAll('[id $= "organization_id"]')).map(function() { return $(this).val(); }).get(); 6347 $('#proceed_to_move_submit_btn').prop( "disabled", arr.includes("--")); 6348} 6349 6350// portal 6351 6352function set_enable_indexing(checkbox) { 6353 ajax_request('/portal/set_enable_indexing?value=' + (checkbox.checked ? 'true' : 'false')); 6354} 6355 6356function set_enable_seo_urls(checkbox) { 6357 ajax_request('/portal/set_enable_seo_urls?value=' + (checkbox.checked ? 'true' : 'false')); 6358} 6359
6360function set_show_contact(checkbox) { 6361 ajax_request('/portal/set_show_contact?value=' + (checkbox.checked ? 'true' : 'false')); 6362} 6363 6364// dashboard 6365 6366function set_dashboard_organization(checkbox) { 6367 ajax_request('/home_configure/display_organization?value=' + (checkbox.checked ? 'true' : 'false')); 6368} 6369 6370// submit the hidden form so large payload goes in POST body 6371 6372function archive_users(link) { 6373 var $link = (window.jQuery ? jQuery(link) : null); 6374 var formSelector = ($link && $link.data('form')) || '#archive_users_form'; 6375 var form = document.querySelector(formSelector); 6376 6377 if (!form) { if (window.console) console.error('archive_users: form not found'); return false; } 6378 6379 // ensure POST 6380 form.method = 'post'; 6381 6382 // double-submit guard 6383 if ($link) { $link.prop('disabled', true); } 6384 6385 // submit 6386 if (form.requestSubmit) { 6387 form.requestSubmit(); 6388 } else { 6389 form.submit(); 6390 } 6391 return false; 6392} 6393 6394// people 6395 6396function update_administrator(checkbox, index) { 6397 if (checkbox.checked) { 6398 show_element('administrator_' + index); 6399 } else { 6400 hide_element('administrator_' + index); 6401 } 6402} 6403 6404function confirm_teacher_role_remove(checkbox, message) { 6405 if (!checkbox.checked) { 6406 var confirmation = confirm(message); 6407 if (!confirmation) { 6408 // If the user cancels, prevent unchecking the checkbox 6409 checkbox.checked = true; 6410 } 6411 } 6412} 6413function update_account_type(administrator) { 6414 if (administrator) { 6415 show_element('full_administrator'); 6416 } else { 6417 hide_element('full_administrator'); 6418 } 6419} 6420 6421// rsvp 6422 6423function update_rsvp(controller, id, calendar_id, event_id, refresh, radio_button, facebox_refresh_url) { 6424 if (refresh) { 6425 window.location.href = '/' + controller + '/update_rsvp/' + id + '?calendar=' + calendar_id + '&event=' + event_id + '&value=' + radio_button.value + '&refresh=true'; 6426 } else { 6427 if(typeof facebox_refresh_url == 'undefined'){ 6428 ajax_request('/' + controller + '/update_rsvp/' + id + '?calendar=' + calendar_id + '&event=' + event_id + '&value=' + radio_button.value); 6429 }else{ 6430 $.get('/' + controller + '/update_rsvp/' + id + '?calendar=' + calendar_id + '&event=' + event_id + '&value=' + radio_button.value, function(){ 6431 $.facebox({'ajax': facebox_refresh_url}); 6432 }); 6433 } 6434 } 6435} 6436 6437// skills 6438 6439function set_default_learning_circle_scope(dropdown) { 6440 ajax_request('/goals_admin/set_default_learning_circle_scope?value=' + dropdown.value); 6441} 6442 6443// tips 6444 6445function show_tip(name) { 6446 show_element('show_' + name); 6447 hide_element('hide_' + name); 6448 ajax_request('/tips/show?value=' + name); 6449} 6450 6451function hide_tip(name) { 6452 show_element('hide_' + name); 6453 hide_element('show_' + name); 6454 ajax_request('/tips/hide?value=' + name); 6455} 6456 6457// questions 6458 6459function submit_freeform(operation, validation_method) { 6460 if (typeof validation_method === 'function' ? validation_method() : true) { 6461 set_value('operation', operation); 6462 submit_form('response'); 6463 } else { 6464 // Content needs change? 6465 $.alert({title: 'Alert', content: 'There is no content!'}); 6466 } 6467} 6468 6469function submit_new_question(operation) { 6470 set_value('operation', operation); 6471 submit_form('question'); 6472} 6473 6474function freeform_validation() { 6475 var editor = tinyMCE.activeEditor; 6476 if (typeof editor !== 'undefined') { 6477 var content = editor.getContent(); 6478 var files_count = 0; 6479 files_count += $('.uploader-list').children('div').length; 6480 files_count += $('.uploader-uploaded-list').children('div').length; 6481 files_count += $('input[id*=remove_attachment_]:not(:checked)').length; 6482 if (content.trim().length > 0) { 6483 return true; 6484 } else if (content.trim().length == 0 && files_count > 0) { 6485 return true; 6486 } 6487 } 6488 return false; 6489} 6490 6491function dropbox_validation() { 6492 var files_count = 0; 6493 files_count += $('.uploader-list').children('div').length; 6494 files_count += $('.uploader-uploaded-list').children('div').length; 6495 return files_count ? true : false; 6496} 6497 6498// reports 6499 6500function submit_report(operation) { 6501 set_value('operation', operation); 6502 submit_form('report'); 6503} 6504 6505function submit_new_report(operation) { 6506 set_value('operation', operation); 6507} 6508 6509// printing 6510 6511function print_this_page(print_args) { 6512 if(is_mobile_app_mode()){ 6513 // PDF export is not supported in mobile app mode 6514 $.alert({content: 'Printing is not supported in the mobile app.'}); 6515 }else { 6516 if (window.location.hash == "") { 6517 new_location = window.location + (window.location.search == "" ? "?" : "&") + 'print=true' 6518 } else { 6519 new_location = window.location.pathname + (window.location.search == "" ? "?" : "&") + 'print=true' + window.location.hash; 6520 } 6521 6522 if (typeof print_args !== 'undefined') { 6523 let args_array = []; 6524 for (const arg in print_args) { 6525 args_array.push(arg + '=' + print_args[arg]); 6526 } 6527 new_location = new_location + '&' + args_array.join('&'); 6528 } 6529 6530 new_window = window.open(new_location); 6531 if (new_window) { 6532 new_window.onload = function () { 6533 new_window.document.title = window.document.title; 6534 new_window.print(); 6535 setTimeout(function(){ 6536 new_window.close(); 6537 }, 300); 6538 }; 6539 } 6540 } 6541} 6542 6543function no_print_column(new_window, selector){ 6544 elements = new_window.document.querySelectorAll(selector); 6545 6546 for (var i = 0; i < elements.length; i++) { 6547 elements[i].style.display="none"; 6548 } 6549} 6550 6551function fix_colspan_userid_passwords() { 6552 var mediaQueryList = window.matchMedia('print'); 6553 mediaQueryList.addListener(function(mql) { 6554 if (mql.matches) { 6555 $("table th#to-print[colspan=2]").attr('colspan',0); //fix colspan from members/userid_passwords 6556 console.log('onbeforeprint'); 6557 } else { 6558 $("table th#to-print").attr('colspan',2); //fix colspan from members/userid_passwords 6559 console.log('onafterprint'); 6560 } 6561 }); 6562} 6563 6564/**=================== 6565 * =================== 6566 * DEMO PRINT Function 6567 * =================== 6568 * ====== START ====== 6569 * */ 6570 6571function print_pdf(options) { 6572 var location = window.location; 6573 var pathname = (location.pathname.indexOf('/', 1) == -1 ? location.pathname + '/index' : location.pathname); 6574 var query_string = []; 6575 6576 if (options) { 6577 $.each(options, function(key, value) { 6578 query_string.push(key + '=' + encodeURIComponent(value)); 6579 }); 6580 6581 query_string = '?' + query_string.join('&'); 6582 } else { 6583 query_string = location.search; 6584 } 6585 6586 if(is_mobile_app_mode()){ 6587 window.parent.postMessage("{\"method\": \"loadBrowser\", \"href\": \"" + location.protocol + "//" + location.host + pathname + ".pdf" + query_string + "\"}", "*"); 6588 }else{ 6589 window.open(location.protocol + "//" + location.host + pathname + ".pdf" + query_string); 6590 } 6591} 6592 6593function popup_with_print(data, title, window_parent) { 6594 var windowUrl = 'Student list'; 6595 var uniqueName = new Date(); 6596 var windowName = 'Print' + uniqueName.getTime(); 6597 var printWindow = window.open(windowUrl, windowName, 'left=0,top=0,width=1000,height=700'); 6598
6599 printWindow.document.write('<html><head><title>' + title + '</title>'); 6600 printWindow.document.write('<link href="/stylesheets/base-colors-user.css" media="screen,print" rel="stylesheet" type="text/css" /> \ 6601 <link href="/stylesheets/themes/monochrome_user.css" media="screen,print" rel="stylesheet" title="theme" type="text/css"> \ 6602 <link href="/stylesheets/default-styles.css" media="screen,print" rel="stylesheet" type="text/css" /> \ 6603 <link href="/stylesheets/styles-user.css" media="screen,print" rel="stylesheet" type="text/css" /> \ 6604 <link href="/stylesheets/extra-user.css" media="screen,print" rel="stylesheet" type="text/css" /> \ 6605 <link href="/stylesheets/fonts/font-all.css" media="screen,print" rel="stylesheet" type="text/css" /> \ 6606 <link href="/stylesheets/facebox.css?2" media="screen,print" rel="stylesheet" type="text/css" /> \ 6607 <link href="/stylesheets/print.css?2" media="screen,print" rel="stylesheet" type="text/css" />'); 6608 printWindow.document.write('</head><body >'); 6609 printWindow.document.write(data);
6610 printWindow.document.write('</body></html>'); 6611 printWindow.document.close(); 6612 6613 printWindow.focus(); 6614 printWindow.print(); 6615 setTimeout(function(){ 6616 printWindow.close(); 6617 window_parent.close(); 6618 }, 1000); 6619} 6620 6621/**=================== 6622 * ======= END ======= 6623 * =================== 6624 * */ 6625 6626function print_pdf_select(selected) { 6627 var location = window.location; 6628 var pathname = (location.pathname.indexOf('/', 1) == -1 ? location.pathname + '/index' : location.pathname); 6629 var url = location.protocol + "//" + location.host + pathname + ".pdf" + location.search; 6630 6631 // should really avoid adding duplicate select[] if already in locaation.search 6632 for (var i = 0; i < selected.length; i++) { 6633 if (i == 0) { 6634 if (location.search.length == 0) { 6635 url += '?'; 6636 } else { 6637 url += '&'; 6638 } 6639 } else { 6640 url += '&'; 6641 } 6642 6643 url += ("select[]=" + selected[i]); 6644 } 6645 6646 if(is_mobile_app_mode()){ 6647 window.parent.postMessage("{\"method\": \"loadBrowser\", \"href\": \"" + url + "\"}", "*"); 6648 }else{ 6649 window.open(url); 6650 } 6651} 6652 6653function help_page(anchor, superuser) { 6654 var url = ((anchor == null) ? '/help' : '/help/#' + anchor); 6655 6656 if (superuser) { 6657 window.open(url, 'Help', 'height=700px,width=520px,location=yes,toolbar=no,directories=yes,status=yes,menubar=yes,scrollbars=yes,resizable=yes,modal=no'); 6658 } else { 6659 window.open(url, 'Help', 'height=700px,width=520px,toolbar=no,directories=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,modal=yes'); 6660 } 6661} 6662 6663function getScrollXY() { 6664 var scrOfX = 0, scrOfY = 0; 6665 6666 if ( typeof (window.pageYOffset) == 'number') { 6667 // Netscape compliant 6668 scrOfY = window.pageYOffset; 6669 scrOfX = window.pageXOffset; 6670 } else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) { 6671 // DOM compliant 6672 scrOfY = document.body.scrollTop; 6673 scrOfX = document.body.scrollLeft; 6674 } else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) { 6675 // IE6 standards compliant mode 6676 scrOfY = document.documentElement.scrollTop; 6677 scrOfX = document.documentElement.scrollLeft; 6678 } 6679 6680 return [scrOfX, scrOfY]; 6681} 6682 6683// event is `this`: an <a href="..."> exposes it as the `.href` DOM property, 6684// but a <button> (rendered when the click itself is intercepted, e.g. by the 6685// action toolbar) does not, even though it still carries a plain href 6686// attribute -- fall back to reading that directly. 6687function submit_form_action_url(event) { 6688 return event.href || event.getAttribute('href'); 6689} 6690 6691function submit_form_with_confirm(form_id, event, prompt) { 6692 $.confirm({ 6693 content: prompt, 6694 confirm: function(){ 6695 var form = $('#' + form_id); 6696 form.attr('method', 'POST'); 6697 form.attr('action', submit_form_action_url(event)); 6698 form.submit(); 6699 } 6700 }); 6701} 6702 6703function submit_form_without_confirm(form_id, event) { 6704 var form = $('#' + form_id); 6705 form.attr('method', 'POST'); 6706 form.attr('action', submit_form_action_url(event)); 6707 form.submit(); 6708} 6709 6710// launch video 6711 6712function launch_video(id, url, height, width, mobile_app, resume_video) { 6713 var extra_params = "&require_video_completion=" + (typeof window.require_video_completion !== 'undefined').toString() + "&resume_video=" + (typeof resume_video !== 'undefined').toString(); 6714 6715 if (typeof window.autoplay !== 'undefined' && window.autoplay) { 6716 extra_params += "&autoplay=true" 6717 } 6718 6719 if (mobile_app) { 6720 window.parent.postMessage("{\"method\": \"loadBrowser\", \"href\": \"/video_player?id=" + id + "&url=" + url + extra_params + "\"}", "*"); 6721 } else { 6722 window.open('/video_player?id=' + id + '&url=' + url + extra_params, 'VIDEO', 'height=' + height + 'px,width=' + width + 'px,toolbar=no,directories=no,location=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,modal=no'); 6723 } 6724} 6725 6726// launch popup 6727 6728function popup(title, url, height, width) { 6729 window.open(url, title, 'height=' + height + 'px,width=' + width + 'px,toolbar=no,directories=no,location=no,status=yes,menubar=no,scrollbars=yes,resizable=yes,modal=no'); 6730} 6731 6732// table item selection 6733 6734function toggle_all(checkbox, disable_message, target) { 6735 disable_message = disable_message || false; 6736 target = target || false; 6737 6738 var form = $(checkbox).closest('form'); 6739 console.log('form = ' + form); 6740 var form_id = form.attr('id'); 6741 console.log('form_id = ' + form_id); 6742 var checkboxes; 6743 var data = form.data('table'); 6744 6745 if (target) { 6746 checkboxes = $(target).find('tr td:nth-child(1) input[type=checkbox]'); 6747 } else { 6748 checkboxes = form.find('tr td:nth-child(1) input[type=checkbox], tr td:nth-child(2) input[type=checkbox]'); 6749 } 6750 6751 console.log('data = ' + data + ', data.count = ' + data.count + ', data.size = ' + data.size + ' disable_message = ' + disable_message); 6752 if ((data != null) && (data.count > data.size) && !disable_message) { 6753 console.log('should check if to show message'); 6754 if (checkbox.checked) { 6755 var tr = form.find('tr:eq(0)'); 6756 console.log('should show message'); 6757 tr.after("<tr><td style='background:#E0F1ff;' colspan='100'>" + you_have_selected_all_text + " <a class='select_all' href='javascript:select_all_items(\"" + form_id + "\");' style='vertical-align:0;'>" + select_all_items_text + "</a>" + "</td></tr>"); 6758 } else {
6759 console.log('should delete message'); 6760 form.find('tr:eq(1)').remove(); 6761 } 6762 } 6763 6764 for (var i = 0; i < checkboxes.length; i++) { 6765 var row_checkbox = checkboxes[i]; 6766 row_checkbox.checked = checkbox.checked; 6767 var row = $(row_checkbox).closest('tr'); 6768 6769 if (checkbox.checked) { 6770 row.addClass('highlight'); 6771 } else { 6772 row.removeClass('highlight'); 6773 } 6774 } 6775 6776 if ((data != null) && data.popup) { 6777 if (checkbox.checked) { 6778 show_options_bar(form); 6779 } else { 6780 hide_options_bar(form); 6781 } 6782 } 6783} 6784 6785function toggle(checkbox, event) { 6786 // toggle the table row background color 6787 var form = $(checkbox).closest('form'); 6788 6789 if ((event.shiftKey == 1) && (last_toggled_id != null) && (last_toggled_id != checkbox.value)) { 6790 var checkboxes = form.find('input[type=checkbox]'); 6791 6792 // find the one that was last tagged 6793 for (var i = 0; i < checkboxes.length; i++) { 6794 var row_checkbox = checkboxes[i]; 6795 6796 if (row_checkbox.value == last_toggled_id) { 6797 start = i; 6798 } 6799 6800 if (row_checkbox.value == checkbox.value) { 6801 stop = i; 6802 } 6803 } 6804 6805 if (start > stop) { 6806 var tmp = start; 6807 start = stop; 6808 stop = tmp; 6809 } 6810 6811 for (var i = start; i <= stop; i++) { 6812 var row_checkbox = checkboxes[i]; 6813 row_checkbox.checked = checkbox.checked; 6814 var row = $(row_checkbox).closest('tr'); 6815 checkbox.checked ? row.addClass('highlight') : row.removeClass('highlight'); 6816 } 6817 } else { 6818 var row = $(checkbox).closest('tr'); 6819 checkbox.checked ? row.addClass('highlight') : row.removeClass('highlight'); 6820 } 6821 6822 // remember the last toggle 6823 last_toggled_id = checkbox.value; 6824 6825 // update top bar 6826 update_options_bar(form); 6827} 6828 6829function checked_toggle(id) { 6830 var checkbox = $(":checkbox[value=" + id + "]"); 6831 var row = $(checkbox).closest('tr'); 6832 row.css('background', '#FFF6BA'); 6833} 6834 6835function toggle_all_lessons(value, link) { 6836 $('#lessons').find('input[name="select[]"]').prop('checked', value); 6837 $(link).attr('onclick', 'toggle_all_lessons(' + (value ? 'false' : 'true') + ', this)'); 6838 6839 if (value) { 6840 $(link).html('<i class="checkboxUnchecked"></i>' + deselect_all_text); 6841 $('.lesson_boxes > div').addClass('highlight'); 6842 $('.modern_module_row').addClass('highlight'); 6843 } else { 6844 $(link).html('<i class="checkboxChecked"></i>' + select_all_text); 6845 $('.lesson_boxes > div').removeClass('highlight'); 6846 $('.modern_module_row').removeClass('highlight'); 6847 } 6848} 6849 6850function toggle_all_groups(value, link) { 6851 var container = $('.catalog_boxes'); 6852 container.find('input[name="select[]"]').prop('checked', value); 6853 $(link).attr('onclick', 'toggle_all_groups(' + (value ? 'false' : 'true') + ', this)'); 6854 6855 if (value) { 6856 $(link).html('<i class="checkboxUnchecked"></i>' + deselect_all_text); 6857 container.find(' > *').addClass('highlight'); 6858 } else { 6859 $(link).html('<i class="checkboxChecked"></i>' + select_all_text); 6860 container.find(' > *').removeClass('highlight'); 6861 } 6862} 6863 6864function toggle_all_chat_rooms(value, link) { 6865 var container = $('.catalog_boxes'); 6866 container.find('input[name="select[]"]').prop('checked', value); 6867 $(link).attr('onclick', 'toggle_all_chat_rooms(' + (value ? 'false' : 'true') + ', this)'); 6868 6869 if (value) { 6870 $(link).html('<i class="checkboxUnchecked"></i>' + deselect_all_text); 6871 container.find(' > *').addClass('highlight'); 6872 } else { 6873 $(link).html('<i class="checkboxChecked"></i>' + select_all_text); 6874 container.find(' > *').removeClass('highlight'); 6875 } 6876} 6877 6878function toggle_all_games(value, link) { 6879 var container = $('.catalog_boxes'); 6880 container.find('input[name="select[]"]').prop('checked', value); 6881 $(link).attr('onclick', 'toggle_all_games(' + (value ? 'false' : 'true') + ', this)'); 6882 6883 if (value) { 6884 $(link).html('<i class="checkboxUnchecked"></i>' + deselect_all_text); 6885 container.find(' > *').addClass('highlight'); 6886 } else { 6887 $(link).html('<i class="checkboxChecked"></i>' + select_all_text); 6888 container.find(' > *').removeClass('highlight'); 6889 } 6890} 6891 6892function toggle_all_goals(value, link) { 6893 $('.goal_list').find('input[name="select[]"]').prop('checked', value); 6894 $(link).attr('onclick', 'toggle_all_goals(' + (value ? 'false' : 'true') + ', this)'); 6895 6896 if (value) { 6897 $(link).html('<i class="checkboxUnchecked"></i>' + deselect_all_text); 6898 $('.goal_list .modern_module_row').addClass('highlight'); 6899 } else { 6900 $(link).html('<i class="checkboxChecked"></i>' + select_all_text); 6901 $('.goal_list .modern_module_row').removeClass('highlight'); 6902 } 6903} 6904 6905function toggle_all_bundle_items(value, link) { 6906 $('.goal_list').find('input[name="select[]"]').prop('checked', value); 6907 $(link).attr('onclick', 'toggle_all_bundle_items(' + (value ? 'false' : 'true') + ', this)'); 6908 6909 if (value) { 6910 $(link).html('<i class="checkboxUnchecked"></i>' + deselect_all_text); 6911 $('.goal_list .modern_module_row').addClass('highlight'); 6912 } else { 6913 $(link).html('<i class="checkboxChecked"></i>' + select_all_text); 6914 $('.goal_list .modern_module_row').removeClass('highlight'); 6915 } 6916} 6917 6918function toggle_all_subscription_items(value, link) { 6919 $('.goal_list').find('input[name="select[]"]').prop('checked', value); 6920 $(link).attr('onclick', 'toggle_all_subscription_items(' + (value ? 'false' : 'true') + ', this)'); 6921 6922 if (value) { 6923 $(link).html('<i class="checkboxUnchecked"></i>' + deselect_all_text); 6924 $('.goal_list .modern_module_row').addClass('highlight'); 6925 } else { 6926 $(link).html('<i class="checkboxChecked"></i>' + select_all_text); 6927 $('.goal_list .modern_module_row').removeClass('highlight'); 6928 } 6929} 6930 6931function goal_row_click(event, element_id){ 6932 if (!$(event.target).is("label") && !$(event.target).is("a")) { 6933 window.location = document.getElementById(element_id).querySelector('.goal_list h2 > a').href; 6934 } 6935} 6936 6937function bundle_item_row_click(event, element_id){ 6938 if (!$(event.target).is("label") && !$(event.target).is("a")) { 6939 window.location = document.getElementById(element_id).querySelector('.goal_list h2 > a').href; 6940 } 6941} 6942 6943function subscription_item_row_click(event, element_id){ 6944 if (!$(event.target).is("label") && !$(event.target).is("a")) { 6945 window.location = document.getElementById(element_id).querySelector('.goal_list h2 > a').href; 6946 } 6947} 6948function toggle_all_users(value, link) { 6949 $('.user_boxes').find('input[name="select[]"]').prop('checked', value); 6950 $(link).attr('onclick', 'toggle_all_users(' + (value ? 'false' : 'true') + ', this)'); 6951 6952 if (value) { 6953 $(link).html('<i class="checkboxUnchecked"></i>' + deselect_all_text); 6954 $('.user_boxes > a').addClass('highlight'); 6955 6956 if ($('.search-navigation').length > 0) { 6957 $('#select_all_warning').html("<p>" + you_have_selected_all_text + " <a href='javascript:select_all_tiled_users();'>" + select_all_items_text + "</a></p>").show(); 6958 } 6959 } else { 6960 $(link).html('<i class="checkboxChecked"></i>' + select_all_text); 6961 $('.user_boxes > a').removeClass('highlight'); 6962 $('#select_all_warning').hide(); 6963 } 6964} 6965 6966function toggle_all_awards(value, link) { 6967 $('.user_boxes').find('input[name="select[]"]').prop('checked', value); 6968 $(link).attr('onclick', 'toggle_all_awards(' + (value ? 'false' : 'true') + ', this)'); 6969 6970 if (value) { 6971 $(link).html('<i class="checkboxUnchecked"></i>' + deselect_all_text); 6972 $('.user_boxes > *').addClass('highlight'); 6973 6974 if ($('.search-navigation').length > 0) { 6975 $('#select_all_warning').html("<p>" + you_have_selected_all_text + " <a href='javascript:select_all_tiled_awards();'>" + select_all_items_text + "</a></p>").show(); 6976 } 6977 } else { 6978 $(link).html('<i class="checkboxChecked"></i>' + select_all_text); 6979 $('.user_boxes > *').removeClass('highlight'); 6980 $('#select_all_warning').hide(); 6981 } 6982} 6983function init_options_bar(form_id) { 6984 var form = $('#' + form_id); 6985 update_options_bar(form); 6986} 6987 6988function update_options_bar(form) { 6989 var data = form.data('table'); 6990 6991 if (data != null && data.popup) { 6992 if (form.find("input[type=checkbox][name='select[]']:checked").length) { 6993 show_options_bar(form); 6994 } else { 6995 hide_options_bar(form); 6996 } 6997 } 6998} 6999 7000function show_options_bar(container) { 7001 var div = container.find('.optionsRibbonTable_separate'); 7002 7003 if (div.length) { 7004 div.css('display', ''); 7005 } 7006} 7007 7008function hide_options_bar(container) { 7009 var div = container.find('.optionsRibbonTable_separate'); 7010 7011 if (div.length) { 7012 div.css('display', 'none'); 7013 } 7014} 7015 7016function show_options_bar_for(form_id) { 7017 var form = $('#' + form_id); 7018 var data = form.data('table'); 7019 7020 if (data != null && data.popup) { 7021 var table = form.find('table'); 7022 show_options_bar(table); 7023 } 7024} 7025 7026function select_all_items(form_id) { 7027 var form = $('#' + form_id); 7028 var form_id = form.attr('id'); 7029 var tr = form.find('tr:eq(1)'); 7030 var td = tr.find('td'); 7031 td.html(all_items_selected_text + " <a class='select_all' href='javascript:unselect_all_items(\"" + form_id + "\");' style='vertical-align:0;'>" + clear_selection_text + "</a>"); 7032 td.after("<input type='hidden' name='select_all' value='true'>"); 7033} 7034 7035function unselect_all_items(form_id) { 7036 var form = $('#' + form_id); 7037 form.find('tr:eq(1)').remove(); 7038 var checkboxes = form.find('input[type=checkbox]'); 7039 7040 for (var i = 0; i < checkboxes.length; i++) { 7041 var checkbox = checkboxes[i]; 7042 checkbox.checked = false;
7043 var row = $(checkbox).closest('tr'); 7044 row.removeClass('highlight'); 7045 } 7046 7047 var data = form.data('table'); 7048 7049 if (data != null && data.popup) { 7050 var table = form.find('table'); 7051 hide_options_bar(table); 7052 } 7053} 7054 7055function select_all_tiled_users() { 7056 $('.user_boxes').before("<input type='hidden' name='select_all' id='select_all_flag' value='true'>"); 7057 $('#select_all_warning').html("<p>" + all_items_selected_text + " <a class='select_all' href='javascript:unselect_all_tiled_users();' style='vertical-align:0;'>" + clear_selection_text + "</a></p>"); 7058} 7059 7060function unselect_all_tiled_users() { 7061 $('#select_all_flag').remove(); 7062 toggle_all_users(false, '#toggle_users_link'); 7063} 7064 7065function set_select(form_id, checkbox) { 7066 var checkboxes = $('input[name="' + form_id + '[]"]'); 7067 7068 for (var i = 0; i < checkboxes.length; i++) { 7069 checkboxes[i].checked = checkbox.checked; 7070 } 7071} 7072 7073// checkbox utility 7074 7075function check_s(checkbox) { 7076 return (checkbox.checked == true ? 'true' : 'false'); 7077} 7078 7079// optionsRibbon toggle 7080 7081function optionsRibbonToggle(name1, name2, thisLink) { 7082 $(thisLink).closest('ul').siblings().removeClass('selected'); 7083 $(thisLink).closest('ul').addClass('selected'); 7084 show_element(name1); 7085 hide_element(name2); 7086} 7087 7088// abstractions 7089 7090function expand(label) { 7091 show_element('remaining_' + label); 7092 hide_element(label); 7093} 7094 7095function collapse(label) { 7096 show_element(label); 7097 hide_element('remaining_' + label); 7098} 7099 7100function show_element(name) { 7101 $('#' + name).show(); 7102 if ($('#' + name).find('textarea').hasClass('hasEditor')) { 7103 $('.tox div.tox-editor-header').each(function(){ 7104 $(this).removeAttr('style'); 7105 }) 7106 } 7107} 7108 7109function hide_element(name) { 7110 $('#' + name).hide(); 7111} 7112 7113function set_style_element(name, style) { 7114 $('#' + name).css(style); 7115} 7116
7117function highlight_element(name, parent) { 7118 if( parent) { 7119 $('#' + name).parent().effect("highlight", {}, 3000); 7120 } else { 7121 $('#' + name).effect("highlight", {}, 3000); 7122 } 7123} 7124 7125function fade_element(name) { 7126 $('#' + name).fadeOut(); 7127} 7128 7129function remove_element(name) { 7130 $('#' + name).remove(); 7131} 7132 7133function focus_element(name) { 7134 if(!is_mobile_app_mode()){ 7135 var el = $('#' + name); 7136 if (el.val() && (el.is('input') || el.is('textarea'))) { 7137 var length = el.val().length; 7138 el.focus()[0].setSelectionRange(length, length); 7139 } else { 7140 el.focus(); 7141 } 7142 } 7143} 7144 7145function clear_value(name) { 7146 $('#' + name).val(''); 7147} 7148 7149function get_value(name) { 7150 return $('#' + name).val(); 7151} 7152 7153function set_value(name, value) { 7154 $('#' + name).val(value); 7155} 7156 7157function is_checked(name) { 7158 return $('#' + name).attr('checked'); 7159} 7160 7161function set_checked(name, value) { 7162 return $('#' + name).attr('checked', value); 7163} 7164 7165function set_html(name, value) { 7166 $('#' + name).html(value); 7167} 7168 7169function ajax_request(url, options) { 7170 if (options == null) { 7171 $.ajax({ 7172 url : url, 7173 type : 'POST' 7174 }); 7175 } else { 7176 $.ajax({ 7177 url : url, 7178 type : 'POST', 7179 async : options.asynchronous 7180 }); 7181 } 7182} 7183 7184function get_ajax_response(url, data, async) { 7185 var result; 7186 7187 if (async == null) { 7188 $.ajax({ 7189 url : url, 7190 type : 'POST', 7191 dataType: data, 7192 success: function(response) { 7193 result = response; 7194 } 7195 }); 7196 } else { 7197 $.ajax({ 7198 url : url, 7199 type : 'POST', 7200 dataType: data, 7201 async : async, 7202 success: function(response) { 7203 result = response; 7204 } 7205 }); 7206 } 7207 7208 return result; 7209} 7210 7211function get_ajax_response_async(url, data, callback) { 7212 $.ajax({ 7213 url : url, 7214 type : 'POST', 7215 dataType: data, 7216 success: callback 7217 }); 7218} 7219 7220function ajax_update(name, url, options) { 7221 $.post(url, function(data) { 7222 set_html(name, data); 7223 }); 7224} 7225function ajax_update_data(name, url, options) { 7226 data = options; 7227 $.post(url, data, function(data) { 7228 set_html(name, data); 7229 }); 7230} 7231 7232function submit_form(name) { 7233 $('#' + name).submit(); 7234} 7235 7236function link_to_ajax(link_element, container_selector) { 7237 Excalibur.Location_tools.add_load_indicator($(container_selector), 100); 7238 7239 $.get($(link_element).attr('href'), function(data){ 7240 setTimeout(function(){ $(container_selector).removeClass('extended-load').html(data); }, 200); 7241 }); 7242 7243 return false; 7244} 7245 7246// reusable excalibur-click functions 7247 7248function toggle_visibility() { 7249 if (this.attr('aria-expanded') == 'true') { 7250 this.attr('aria-expanded', false); 7251 } else { 7252 this.attr('aria-expanded', true); 7253 } 7254 7255 this.find('> *').toggle();// toggle visibility icons 7256 $('#' + this.attr('data-element')).toggle();// toggle element 7257} 7258 7259// portal login 7260 7261function find_portal() { 7262 $('nav.mainNav ol > li:last-child div').removeClass('dDownShow'); 7263 7264 $.facebox({ 7265 'ajax' : '/info/find_portal?name=' + $('#portal_name').val() 7266 }); 7267} 7268 7269function find_portal_new() { 7270 if($('#portal_name').val().length > 0) { 7271 $.facebox({ 7272 'ajax': '/info/find_portal?name=' + $('#portal_name').val() 7273 }); 7274 }else{ 7275 $('#portal_name').css('border', '1px solid red').focus(); 7276 } 7277} 7278 7279function submit_signup(){ 7280 add_progress($('.signupForm button[type="submit"]')); 7281} 7282 7283// form concatenation for authorize.net integration 7284 7285function concat_form_fields() { 7286 $('#x_exp_date').val($('#x_month').val() + $('#x_year').val().substr(2,2)); 7287} 7288 7289// display utilities 7290 7291function fade_alert() { 7292 closeAlertTimer = setInterval(function() { 7293 $('div.info').animate({ 7294 height : '0', 7295 opacity : '0' 7296 }, 500, function() { 7297 $(this).css('display', 'none'); 7298 }); 7299 }, 3000); 7300} 7301 7302function get_maximum_upload_size() { 7303 return window.maxUploadLimit + 'mb'; 7304} 7305 7306// show timer function 7307 7308function show_quiz_timer(id) { 7309 $("#" + id).on("change", function(){ 7310 if ( $(this).is(':checked') ) { 7311 show_element('timer'); 7312 } else { 7313 hide_element('timer'); 7314 } 7315 }); 7316} 7317 7318// show options 7319 7320function show_assignment_option_check(changed, hidden) { 7321 $("#" + changed).on("change", function(){ 7322 if ( $(this).is(':checked') ) { 7323 show_element(hidden); 7324 } else { 7325 hide_element(hidden); 7326 } 7327 }); 7328} 7329 7330function show_assignment_option_radio(changed, value, hidden) { 7331 $("input[id^='" + changed + "']").on("change", function () { 7332 var show = false;
7333 7334 if (Array.isArray(value)) { 7335 show = value.includes($(this).val()); 7336 } else { 7337 show = $(this).val() == value; 7338 } 7339 7340 if (show) { 7341 show_element(hidden); 7342 } else { 7343 hide_element(hidden); 7344 } 7345 }); 7346} 7347 7348// login credentials 7349 7350function display_login_credentials(secure_protocol, current_host, ssl_host, user_id, auth_token) { 7351 if (ssl_host.toUpperCase() == current_host.toUpperCase()) { 7352 $.ajax({ 7353 type : 'POST', 7354 url : secure_protocol + '://' + current_host + '/user/get_login_info/' + user_id + (auth_token ? '?one_time_auth_token=' + auth_token : ''), 7355 dataType : 'json', 7356 success : function(json, text_status, jqXHR) { 7357 $('#userid_placeholder').html(json.userid); 7358 $('#password_placeholder').html(json.password); 7359 }, 7360 error : function(jqXHR, text_status, errorThrown) { 7361 $.alert({content: 'error ' + text_status}); 7362 } 7363 }); 7364 } else { 7365 $.ajax({ 7366 type : 'POST', 7367 url : 'https://' + current_host + '/authentication/get_auth_token', 7368 dataType : 'json', 7369 success : function(json, text_status, jqXHR) { 7370 display_login_credentials(secure_protocol, ssl_host, ssl_host, user_id, json.auth_token); 7371 }, 7372 error : function(jqXHR, text_status, errorThrown) { 7373 $.alert({content: 'error ' + text_status}); 7374 } 7375 }); 7376 } 7377} 7378 7379function display_users_credentials(secure_protocol, current_host, ssl_host, controller, id, auth_token, key, user_allowed) { 7380 if (ssl_host.toUpperCase() == current_host.toUpperCase() || user_allowed) { 7381 var select = []; 7382 7383 $('tr[id^="user_"]').each(function() { 7384 select.push($(this).attr('id').split('_')[1]); 7385 }); 7386 7387 $.ajax({ 7388 type : 'POST', 7389 data : { 7390 'select' : select 7391 }, 7392 url : secure_protocol + '://' + current_host + '/' + controller + '/get_login_info' + (id ? ('/' + id) : '') + (auth_token ? '?one_time_auth_token='
7392+ auth_token : '') + (key ? (auth_token ? '&key=' : '?key=') + key : ''), 7393 dataType : 'json', 7394 success : function(json, text_status, jqXHR) { 7395 for (var i = 0; i < json.users.length; i++) { 7396 var user = json.users[i]; 7397 $('#userid_placeholder_' + user.id).html(user.userid); 7398 $('#password_placeholder_' + user.id).html(user.password); 7399 } 7400 }, 7401 error : function(jqXHR, text_status, errorThrown) { 7402 $.alert({content: 'error ' + text_status}); 7403 } 7404 }); 7405 } else { 7406 $.ajax({ 7407 type : 'GET', 7408 url : 'https://' + current_host + '/authentication/get_auth_token', 7409 dataType : 'json', 7410 success : function(json, text_status, jqXHR) { 7411 display_users_credentials(secure_protocol, ssl_host, ssl_host, controller, id, json.auth_token, key); 7412 }, 7413 error : function(jqXHR, text_status, errorThrown) { 7414 $.alert({content: 'error ' + text_status}); 7415 } 7416 }); 7417 } 7418} 7419 7420// OnChange function for grading 7421 7422function no_grading() { 7423 var id = 'assignmentScore'; 7424 var el = $('#facebox [name="assignment[grading]"]'); 7425 var visible = $('#' + id).css("display"); 7426 7427 if (visible === 'none') { 7428 el.parent().find('> label').addClass('min-w-76'); 7429 } 7430 7431 el.on('change', function() { 7432 var val = $(this).val().toLowerCase(); 7433 var chd = $(this).parent().find('span:first-child'); 7434 var max_score_div = $('#' + id); 7435 var max_score_input = max_score_div.find("#assignment_max_score"); 7436 7437 if (val === 'not graded') { 7438 max_score_div.hide(); 7439 chd.next('label').addClass('min-w-76'); 7440 if(isBlank(max_score_input.val())){ 7441 max_score_input.val(100); 7442 } 7443 } else { 7444 max_score_div.show(); 7445 $(this).parent().find('> label').removeClass('min-w-76'); 7446 } 7447 }); 7448} 7449 7450function no_grading_list() { 7451 var el = $('[name$="[grading]"]'); 7452 7453 el.on('change', function() { 7454 var id = $(this).parent().attr('id'); 7455 var val = $(this).val().toLowerCase(); 7456 var mel = $('.max_score_' + id + ', .max_weight_' + id); 7457 7458 if (val === 'not graded') { 7459 mel.find('span:first-child').show(); 7460 mel.find('span:last-child').hide(); 7461 } else { 7462 mel.find('span:first-child').hide(); 7463 mel.find('span:last-child').show(); 7464 } 7465 }); 7466} 7467 7468/* rule action message support */ 7469 7470function show_message_content() { 7471 $('#message_type input').click(function() { 7472 if ($('#rule_action_message_type_custom').is(':checked')) { 7473 $('.tox div.tox-editor-header').each(function(){ 7474 $(this).removeAttr('style'); 7475 }); 7476 7477 $('#canned_message').hide(); 7478 $('#custom_message').show(); 7479 $('#notification_type').show(); 7480 $('#send_copy_to_manager').show(); 7481 } else if ($('#rule_action_message_type_canned').is(':checked')) { 7482 $('#canned_message').show(); 7483 $('#custom_message').hide(); 7484 $('#notification_type').show(); 7485 $('#send_copy_to_manager').show(); 7486 } else { 7487 $('#canned_message').hide(); 7488 $('#custom_message').hide(); 7489 $('#notification_type').hide(); 7490 $('#send_copy_to_manager').hide(); 7491 } 7492 }); 7493} 7494 7495/** 7496 * ===================================================================== 7497 * Session timeout functionality. Save everything in cookies so it will 7498 * be available inside every window of the browser. 7499 * Cookies expire on browser close ( = no expiration date specified ) 7500 * ===================================================================== 7501 * ===============================START================================= 7502 * ===================================================================== 7503 */ 7504 7505// session timeout -> Everything goes into cookies 7506// session_timeout_warning should not be cookie in order to open the warning pop-up in every window 7507 7508var next_countdown_value = null; 7509var session_timeout_warning = false; 7510var SESSION_WARNING_SECONDS = 30; 7511var SCAN_FRAME_SECONDS = 5; 7512var sessionTimeoutWorker = null; 7513 7514function session_timeout_after(seconds) { 7515 set_lms_cookie('session_timeout_seconds', parseInt(seconds), '/'); 7516 start_session_timeout_timer(); 7517 session_activity_monitor(session_activity_detected_callback); 7518 reset_session_timeout_timer(); 7519} 7520 7521function start_session_timeout_timer() { 7522 // terminate old worker 7523 if (sessionTimeoutWorker) { 7524 sessionTimeoutWorker.terminate(); 7525 } 7526 7527 sessionTimeoutWorker = new Worker('/javascripts/session_timeout_worker.js'); 7528 sessionTimeoutWorker.onmessage = function (event) { 7529 if (event.data[0] === 'decrementSessionCountdown') { 7530 decrement_session_countdown(); 7531 } 7532 } 7533 7534 sessionTimeoutWorker.postMessage(['initializeTimer']); 7535} 7536 7537function session_activity_detected_callback(is_frame){ 7538 if (is_frame) { 7539 window.parent.session_activity_detected(); 7540 } else { 7541 session_activity_detected(); 7542 } 7543} 7544 7545function reset_session_timeout_timer() { 7546 set_lms_cookie('session_timeout_countdown', get_lms_cookie('session_timeout_seconds'), '/'); 7547 next_countdown_value = parseInt(get_lms_cookie('session_timeout_seconds')) - 1; 7548 session_timeout_warning = false;
7549} 7550 7551function decrement_session_countdown() { 7552 // this was originally created for scorm. When scorm opens in a new window, we want to pause the session time out 7553 // to avoid logging the user out when she's working with the system in a window we cannot track. 7554 if(typeof(pause_session_timeout) !== 'undefined' && pause_session_timeout) { 7555 set_lms_cookie('session_timeout_countdown', next_countdown_value, '/'); 7556 return; 7557 } 7558 7559 // make sure that only one window updates the countdown cookie 7560 if ((parseInt(get_lms_cookie('session_timeout_countdown')) - 1) == next_countdown_value) { 7561 set_lms_cookie('session_timeout_countdown', parseInt(get_lms_cookie('session_timeout_countdown')) - 1, '/'); 7562 } 7563 7564 next_countdown_value = parseInt(get_lms_cookie('session_timeout_countdown')) - 1; 7565 7566 if ((parseInt(get_lms_cookie('session_timeout_countdown')) <= SESSION_WARNING_SECONDS) && session_timeout_warning == false) { 7567 session_timeout_warning = true; 7568 $.facebox({'ajax' : '/session_timeout/idle'}); 7569 } else if (parseInt(get_lms_cookie('session_timeout_countdown')) <= 0) { 7570 window.location = '/log_out?timeout=true'; 7571 } else if ((parseInt(get_lms_cookie('session_timeout_countdown')) > SESSION_WARNING_SECONDS) && session_timeout_warning == true) { 7572 session_timeout_warning = false; 7573 $.facebox.close(); 7574 } 7575} 7576 7577function session_activity_detected() { 7578 if (session_timeout_warning && $('#facebox').find('.idle').length != 0) { 7579 $.facebox.close(); 7580 } 7581 7582 reset_session_timeout_timer(); 7583} 7584 7585////////////////////////////////////////// 7586// Session Activity Monitoring 7587////////////////////////////////////////// 7588 7589function session_activity_monitor(on_detect_activity_callback) { 7590 element_activity_detector(document, function(){ on_detect_activity_callback(false) }); 7591 // frame_activity_monitor(undefined, on_detect_activity_callback); 7592 flowplayer_activity_detector(on_detect_activity_callback); 7593 youtube_activity_detector(on_detect_activity_callback); 7594 vimeo_activity_detector(on_detect_activity_callback); 7595} 7596 7597function element_activity_detector(element, on_detect_activity_callback ) { 7598 // the purpose of this variable is to throttle the callbacks 7599 var last_activity_reported_at = 0; 7600 7601 $(element).on('click mouseup mousedown touchend touchstart touchmove mousewheel mousemove keypress keydown', function(e) { 7602 if(Date.now() - last_activity_reported_at >= 1000) { 7603 last_activity_reported_at = Date.now(); 7604 on_detect_activity_callback(); 7605 } 7606 }); 7607} 7608 7609function youtube_activity_detector(on_detect_activity_callback) { 7610 function report_youtube_activity() { 7611 if(youtube_players.some(function(player){ return typeof(player.getPlayerState) !== 'undefined' && player.getPlayerState() === YT.PlayerState.PLAYING })) { 7612 on_detect_activity_callback(); 7613 } 7614 setTimeout(report_youtube_activity, 10000); 7615 } 7616 7617 var youtube_setup_checks = 0 7618 function setup_youtube_after_load() { 7619 // put a limit on the number of checks if sth goes wrong 7620 if(typeof(youtube_players) !== 'undefined' && youtube_players.length > 0){ 7621 report_youtube_activity(); 7622 } else { 7623 youtube_setup_checks +=1 7624 if(youtube_setup_checks < 11) 7625 setTimeout(setup_youtube_after_load, 1000); 7626 } 7627 } 7628 7629 setup_youtube_after_load(); 7630} 7631 7632function vimeo_activity_detector(on_detect_activity_callback){ 7633 // keep state if a video is playing 7634 var video_playing = false; 7635
7636 // check every 10 seconds if a video is playing and callback 7637 function report_video_activity() { 7638 if (video_playing) { 7639 on_detect_activity_callback(); 7640 } 7641 setTimeout(report_video_activity, 10000); 7642 } 7643 7644 function set_vimeo_callbacks() { 7645 vimeo_players.forEach(function(player) { 7646 player.on('play', function() { 7647 video_playing = true; 7648 }); 7649 7650 player.on('pause', function() { 7651 video_playing = false; 7652 }); 7653 7654 player.on('ended', function() { 7655 video_playing = false; 7656 }); 7657 }); 7658 } 7659 7660 var vimeo_setup_checks = 0 7661 function setup_vimeo_after_load() { 7662 // put a limit on the number of checks if sth goes wrong 7663 if(typeof(vimeo_players) !== 'undefined' && vimeo_players.length > 0) { 7664 set_vimeo_callbacks(); 7665 report_video_activity(); 7666 } else { 7667 vimeo_setup_checks += 1 7668 if(vimeo_setup_checks < 11) 7669 setTimeout(setup_vimeo_after_load, 1000); 7670 } 7671 } 7672 7673 setup_vimeo_after_load(); 7674} 7675 7676function flowplayer_activity_detector(on_detect_activity_callback){ 7677 // keep state if a video is playing 7678 var video_playing = false; 7679 7680 // activity status update event 7681 $(window).on('videoActivityDetector.statusUpdate', function(e, statusData){ 7682 if (statusData && statusData.hasOwnProperty('videoPlaying')) { 7683 if (statusData.videoPlaying) { 7684 video_playing = true; 7685 on_detect_activity_callback(); 7686 } else { 7687 video_playing = false; 7688 } 7689 } 7690 }); 7691
7692 // check every 10 seconds if a video is playing call the callback 7693 function report_video_activity() { 7694 if (video_playing) { 7695 on_detect_activity_callback(); 7696 } 7697 setTimeout(report_video_activity, 10000); 7698 } 7699 7700 report_video_activity(); 7701} 7702 7703// Frame activity monitor 7704function frame_activity_monitor(win, on_detect_activity_callback) { 7705 function getInnerFrame(win) { 7706 win = (win || window); 7707 var frames = win.frames; 7708 7709 if (frames.length > 0) { 7710 var i; 7711 7712 for (i=0; i < frames.length; i++) { 7713 element_activity_detector(frames[i], function(){ on_detect_activity_callback(true) }); 7714 7715 getInnerFrame(frames[i]); 7716 } 7717 } else { 7718 return win; 7719 } 7720 } 7721 7722 if (win) { 7723 setInterval(function() { 7724 if (win.length) { 7725 getInnerFrame(win); 7726 } 7727 }, SCAN_FRAME_SECONDS * 1000); 7728 } else if (window.frames.length > 0) { 7729 setInterval(function() { 7730 getInnerFrame(); 7731 }, SCAN_FRAME_SECONDS * 1000); 7732 } 7733} 7734 7735////////////////////////////////////////// 7736// END Session Activity Monitoring 7737////////////////////////////////////////// 7738 7739function display_timeout() { 7740 if ($('#facebox').find('.timeout').length == 0) { 7741 $.facebox({'ajax': '/session_timeout/timeout'}); 7742 } 7743} 7744 7745function display_sync_popup(class_id, sync_job_id) { 7746 if ($('#facebox').find('.sync_popup').length == 0) { 7747 $.facebox({'ajax': '/session_group/sync_from_job/' + class_id + '?sync_job_id=' + sync_job_id}); 7748 } 7749} 7750 7751function display_moved() { 7752 if ($('#facebox').find('.moved').length == 0) { 7753 $.facebox({'ajax': '/portal_moved/message'}); 7754 } 7755} 7756 7757function display_deleted() { 7758 if ($('#facebox').find('.deleted').length == 0) { 7759 $.facebox({'ajax': '/info/deleted'}); 7760 } 7761} 7762 7763function display_sso_error(message, title) { 7764 if ($('body').hasClass('portal') && $('#facebox').find('.sso').length == 0) { 7765 Excalibur.facebox({'ajax': '/sso/error?error=' + encodeURIComponent(message) + (title ? '&title=' + encodeURIComponent(title) : '')}); 7766 } else if ($('body').hasClass('loginPage')) { 7767 var alertBlock = $('<div class="alert_block error" style="width:auto" role="alert"><div class="alert_flex"><div class="alert_icon"><i class="error inverted"></i></div><p></p></div></div>'); 7768 alertBlock.find('p').text(message); 7769 $('#loginForm #alerts').empty().append(alertBlock).show(); 7770 } 7771} 7772 7773/** 7774 * ====================================== 7775 * Standard GET/SET functions for COOKIES 7776 * ====================================== 7777 */ 7778 7779function get_lms_cookie(name) { 7780 var value = document.cookie; 7781 var start = value.indexOf(" " + name + "="); 7782 7783 if (start == -1) { 7784 start = value.indexOf(name + "="); 7785 } 7786 7787 if (start == -1) { 7788 value = null; 7789 } else { 7790 start = value.indexOf("=", start) + 1; 7791 var end = value.indexOf(";", start); 7792 7793 if (end == -1) { 7794 end = value.length; 7795 } 7796 7797 value = unescape(value.substring(start, end)); 7798 } 7799 7800 return value; 7801} 7802 7803function set_lms_cookie(name, value, path, exdays) { 7804 var exdate = new Date(); 7805 exdate.setDate(exdate.getDate() + exdays); 7806 value = escape(value); 7807 7808 if (path != null) { 7809 value += "; path=" + path; 7810 } 7811 7812 if (exdays != null) { 7813 value += "; expires=" + exdate.toUTCString(); 7814 } 7815 7816 document.cookie = name + "=" + value; 7817} 7818 7819/** 7820 * ===================================================================== 7821 * Here is where the dropdown for messages magic happens: 7822 * - infinite scroll with ajax 7823 * - view message / send message popups 7824 * - keep mouse wheel scroll inside the div 7825 * - auto-suggest multiple receivers with remove option ( tag style ) 7826 * - ajax delete 7827 * - reply, reply to forum and send message using ajax 7828 * - IE focus forcer... 7829 * ===================================================================== 7830 * ===============================START================================= 7831 * ===================================================================== 7832 */ 7833 7834/* Message box get message */ 7835var box_offset = 0; 7836var box_limit = 10; 7837var scroll_check_mess = scroll_check_not = true; 7838 7839function call_for_messages(container, controller) { 7840 var holder = $(container).find('.dropDown ul'); 7841 isolatedScroll($(container).find('.dropDown .scroll')); 7842 holder.html('').append('<div class="loader"></div>'); 7843 box_offset = 0; 7844 7845 if (holder.find('li').length == 0) { 7846 ajax_call_for_messages(holder, container, controller); 7847 7848 if (container == '.messagesHolder' && scroll_check_mess) { 7849 exec_scroll(holder, container, controller); 7850 }
7850 else if (container == '.notificationsHolder' && scroll_check_not) { 7851 exec_scroll(holder, container, controller); 7852 } 7853 } 7854 7855 if (container == '.messagesHolder') { 7856 just_read_message(); 7857 } else if (container == '.notificationsHolder') { 7858 just_read_notification(); 7859 } 7860} 7861 7862function ajax_call_for_messages(holder, container, controller) { 7863 $.ajax({ 7864 type : "POST", 7865 url : "/" + controller + "/get_messages", 7866 data : { 7867 offset : box_offset, 7868 limit : box_limit 7869 }, 7870 dataType : "json", 7871 async : false, 7872 success : function(data) { 7873 var k_read_at = false; 7874 7875 holder.find('.loader').remove(); 7876 7877 if (data.count == 0) { 7878 var empty_message_icon = (controller == 'inbox' ? 'messages' : 'notifications'); 7879 var empty_message = (controller == 'inbox' ? no_messages_text : no_notifications_text); 7880 holder.html('').append('<p class="center px14">' + empty_message + '<br><img src="/images/icons/large/empty-' + empty_message_icon + '.svg" width="100" /></p>'); 7881 } else if (data.count >= box_offset) { 7882 for (var i = 0; i < data.messages.length; i++) { 7883 var message = data.messages[i]; 7884 var class_name = message.class_name; 7885 var forum = (message.forum ? message.forum : null); 7886 var html = ''; 7887 7888 html += '<li class="ms-holder message-' + message.id + '" id="message-' + message.id + '">'; 7889 html += '<a href="/' + controller + '/show?popup=true&' + (controller == 'inbox' ? 'message' : 'notification' ) + '=' + message.id + '" onclick="return popup_clicked(this);" class="ms-main-open" role="button">'; 7890 html += '<span class="ms-image"><img src="' + message.photo + '" width="30" height="30" alt="" /></span>'; 7891 html += '<span class="ms-user">' + message.first_name + ' ' + message.last_name; 7892 html += ( class_name ? ' - <span class="ms-class-name">' + class_name + '</span>' : ''); 7893 html += ( forum ? ' <span class="ms-arrow"></span> ' + forum : ''); 7894 html += '</span>'; 7895 html += '<span class="ms-subject">' + message.name + '</span>'; 7896 html += '<span class="ms-date">' + message.date + '</span>'; 7897 html += '</a>'; 7898 7899 html += '<a href="#" excalibur-click="load_un_read_bindings" class="ms-status-holder" role="button">'; 7900 7901 if (message.read_at) { 7902 html += '<span class="ms-status left" data-tooltip="' + mark_as_unread_text + '"><i class="tick icnColor"></i><span class="textOffScreen">Mark as unread</span></span>'; 7903 } else { 7904 html += '<span class="ms-status unread left" data-tooltip="' + mark_as_read_text + '"><i class="xCross icnColor"></i><span class="textOffScreen">Mark as read</span></span>'; 7905 k_read_at = true; 7906 } 7907 7908 html += '</a>'; 7909 html += '</li>'; 7910 7911 holder.append(html); 7912 7913 $('#message-' + message.id + ' a.ms-main-open').on('click', function() { 7914 var parent = $(this).parent(); 7915 7916 if (parent.hasClass('ms-unread')) { 7917 parent.find('.ms-status-holder').html('<span class="ms-status" title="' + mark_as_unread_text + '"><i class="tick icnColor"></i><span class="textOffScreen">Mark as unread</span></span>'); 7918 7919 // change the newAlert counter value after unread message was opened 7920 var newAlert = $(this).parents(container).find('.newAlert'); 7921 var messIcon = newAlert.next('i'); 7922 7923 if (newAlert.length != 0) { 7924 var newAlertValue = parseInt(newAlert.text()); 7925 7926 if (newAlertValue > 1) { 7927 newAlert.text(newAlertValue - 1); 7928 } else { 7929 messIcon.removeClass('messages').addClass('unread'); 7930 newAlert.remove(); 7931 } 7932 } 7933 } 7934 }); 7935 7936 } 7937 } 7938 7939 if ( k_read_at ) { 7940 $(container).find('.markAllAsRead').show(); 7941 } 7942 7943 box_offset += 10; 7944 isolatedScroll($(container).find('.dropDown .scroll')); 7945 } 7946 }); 7947} 7948 7949function load_un_read_bindings() { 7950 var el = this; 7951 var id = el.parent('li').attr('id').split('-')[1]; 7952 7953 if (el.parents('.notificationsHolder').length > 0) {
7954 un_read_update_status('notifications', '.notificationsHolder', id); 7955 } else if (el.parents('.messagesDropDown').length > 0) { 7956 un_read_update_status('inbox', '.messagesHolder', id); 7957 } 7958} 7959 7960function un_read_update_status(controller, container, id) { 7961 $.post('/' + controller + '/mark_un_read', {posting: id}, function(response) { 7962 if (response.status === 'ok') { 7963 un_read_action(container, id); 7964 } else { 7965 alert(response.message); 7966 } 7967 }); 7968} 7969 7970function un_read_action(container, id) { 7971 var el = $(container + ' li.message-' + id); 7972 var status = el.find('span.ms-status i'); 7973 7974 if (status.attr('class').indexOf('xCross') != -1) { 7975 status.removeClass('xCross').addClass('tick'); 7976 status.parent('span').attr('data-tooltip', mark_as_unread_text); 7977 status.parent('span').find('.textOffScreen').text(mark_as_unread_text); 7978 un_read_update_counters(container, -1); 7979 } else { 7980 status.removeClass('tick').addClass('xCross'); 7981 status.parent('span').attr('data-tooltip', mark_as_read_text); 7982 status.parent('span').find('.textOffScreen').text(mark_as_read_text); 7983 un_read_update_counters(container, 1); 7984 } 7985} 7986 7987function un_read_update_counters(container, value) { 7988 var counter = $(container + ' span.newAlert'); 7989 7990 if (counter.length == 0) { 7991 $(container + ' > a').prepend('<span class="newAlert"></span>'); 7992 counter = $(container).find('span.newAlert'); 7993 } 7994 7995 var count = ((counter.text() == '' || isNaN(counter.text())) ? 0 : parseInt(counter.text())) + value; 7996 7997 if (count > 0) { 7998 counter.html(count); 7999 $(container + ' a.markAllAsRead').show(); 8000 8001 if (container == '.messagesHolder' && $(container + ' a i').hasClass('unread')) { 8002 $(container + ' > a i').removeClass('unread').addClass('messages'); 8003 } 8004 } else { 8005 counter.remove(); 8006 $(container + ' a.markAllAsRead').hide(); 8007 8008 if (container == '.messagesHolder' && $(container + ' a i').hasClass('messages')) { 8009 $(container + ' > a i').removeClass('messages').addClass('unread'); 8010 } 8011 } 8012} 8013 8014// scroll 8015 8016function exec_scroll(holder, container, controller) { 8017 $(container).find('.scroll').scroll(function(e) { 8018 if (e.target.scrollTop >= (e.target.scrollHeight - e.target.clientHeight)) { 8019 ajax_call_for_messages(holder, container, controller); 8020 } 8021 }); 8022 8023 if (controller == 'inbox') { 8024 scroll_check_mess = false; 8025 } else if (controller = 'notifications') { 8026 scroll_check_not = false; 8027 } 8028} 8029 8030// Isolate the scroll inside the element from the page 8031 8032function isolatedScroll(element) { 8033 element.bind('mousewheel DOMMouseScroll', function(e) { 8034 var delta = (e.wheelDelta || (e.originalEvent && e.originalEvent.wheelDelta) || -e.detail); 8035 var bottomOverflow = ((this.scrollTop + $(this).outerHeight() - this.scrollHeight) >= 0); 8036 var topOverflow = (this.scrollTop <= 0); 8037 8038 if ((delta < 0 && bottomOverflow) || (delta > 0 && topOverflow)) { 8039 e.preventDefault(); 8040 } 8041 }); 8042 8043 return element; 8044} 8045 8046function call_for_jobs(container) { 8047 $.get('/profile_jobs/jobs', function(html) { 8048 $(container + ' ul').html(html); 8049 }); 8050} 8051 8052// memory variable with the user selections field, 8053// it's an array of Objects, every Object being a selection 8054// we need it to re-populate the field if error in sending process 8055var select2_memory = {}; 8056select2_memory.to = []; 8057select2_memory.cc = []; 8058select2_memory.bcc = []; 8059var select2_data = []; 8060var select2_data_size = 0; 8061 8062var select2_data_cc = []; 8063var select2_data_cc_size = 0; 8064 8065// Auto suggest input for the send message box 8066 8067function autoSuggestInit(element, selected_elems_size, selected_elems) { 8068 var el = $(element), results, preload_data, ln, fn, tln, tfn, tlnfn, tfnln, q; 8069 var recipient_type = element.split("#")[1]; 8070 8071 select2_memory.to = []; 8072 select2_memory.cc = []; 8073 select2_memory.bcc = []; 8074 8075 if (selected_elems != undefined && (selected_elems.length > 0)) { 8076 select2_memory[recipient_type] = selected_elems; 8077 } 8078 8079 var max_selection_size; 8080 if (recipient_type == 'to') { 8081 select2_data = select2_memory.to; 8082 select2_data_size = parseInt(selected_elems_size); 8083 max_selection_size = (select2_data.length > 0 ? (select2_data.length + 10) : 10); 8084 } else if (recipient_type == 'cc') { 8085 select2_data_cc = select2_memory.cc; 8086 select2_data_cc_size = parseInt(selected_elems_size); 8087 max_selection_size = (select2_data_cc.length > 0 ? (select2_data_cc.length + 10) : 10); 8088 } else { 8089 max_selection_size = 10; 8090 } 8091 8092 el.select2({ 8093 multiple : true, 8094 maximumSelectionSize : max_selection_size, // for limitation of people number in the "to" fields 8095 minimumInputLength : 2, // minimum chars to start the suggest query
8096 ajax : { 8097 type : "GET", 8098 url : "/inbox/suggest_users", 8099 dataType : 'json', 8100 quietMillis : 500, // bigger delay before ajax is called 8101 data : function(term) { 8102 q = term; 8103 return { 8104 name : q 8105 }; 8106 }, 8107 results : function(data) { 8108 results = { 8109 results : [] 8110 }; 8111 preload_data = data.results; 8112 8113 $.each(preload_data, function() { 8114 ln = this.last_name; 8115 fn = this.first_name; 8116 tln = ln.toUpperCase(); 8117 tfn = fn.toUpperCase(); 8118 tfnln = tfn + ' ' + tln; 8119 tlnfn = tln + ' ' + tfn; 8120 8121 q = q.trim(); 8122 q = q.toUpperCase(); 8123 8124 if (tln.indexOf(q) >= 0 || tfn.indexOf(q) >= 0 || tfnln.indexOf(q) >= 0 || tlnfn.indexOf(q) >= 0) { 8125 results.results.push({ 8126 id : this.id, 8127 text : fn + ' ' + ln 8128 }); 8129 } 8130 }); 8131 8132 // the #to input will contain the ids: id1,id2,id3 8133 return results; 8134 } 8135 } 8136 }).on('change', function() { 8137 select2_memory[$(this).attr('id')] = $(this).select2('data'); 8138 8139 if ($(this).attr('id') == 'to') { 8140 select2_data = select2_memory[$(this).attr('id')]; 8141 select2_data_size = select2_data.length; 8142 } 8143 if ($(this).attr('id') == 'cc') { 8144 select2_cc_data = select2_memory[$(this).attr('id')]; 8145 select2_cc_data_size = select2_cc_data.length; 8146 } 8147 }); 8148 8149 if (select2_memory[recipient_type].length > 0) { 8150 el.data().select2.updateSelection(select2_memory[recipient_type]); 8151 8152 if (select2_data_size > 5 && recipient_type == 'to') { 8153 setTimeout(function() { 8154 add_sender_placeholder(select2_data, select2_data_size, '#s2id_to'); 8155 }, 100); 8156 } 8157 if (select2_data_cc_size > 5 && recipient_type == 'cc' ) { 8158 setTimeout(function() { 8159 add_sender_placeholder(select2_data_cc, select2_data_cc_size, '#s2id_cc'); 8160 }, 100); 8161 } 8162 } 8163} 8164 8165function autoSuggestSpecificInit(element, selected_elems_size, selected_elems) { 8166 var el = $(element), results, preload_data, ln, fn, tln, tfn, tlnfn, tfnln, q; 8167 var recipient_type = element.split("#")[1]; 8168 8169 select2_memory.to = []; 8170 8171 if (selected_elems != undefined && (selected_elems.length > 0)) { 8172 select2_memory[recipient_type] = selected_elems; 8173 } 8174 8175 select2_data = select2_memory.to; 8176 select2_data_size = parseInt(selected_elems_size); 8177 8178 el.select2({ 8179 multiple : true, 8180 maximumSelectionSize : 1, // for limitation of people number in the "to" fields 8181 minimumInputLength : 2, // minimum chars to start the suggest query
8182 ajax : { 8183 type : "GET", 8184 url : "/inbox/suggest_specific_users", 8185 dataType : 'json', 8186 quietMillis : 500, // bigger delay before ajax is called 8187 data : function(term) { 8188 q = term; 8189 return { 8190 name : q 8191 }; 8192 }, 8193 results : function(data) { 8194 results = { 8195 results : [] 8196 }; 8197 preload_data = data.results; 8198 8199 $.each(preload_data, function() { 8200 ln = this.last_name; 8201 fn = this.first_name; 8202 tln = ln.toUpperCase(); 8203 tfn = fn.toUpperCase(); 8204 tfnln = tfn + tln; 8205 tlnfn = tln + tfn; 8206 8207 q = q.replace(" ", ""); 8208 q = q.toUpperCase(); 8209 8210 if (tln.indexOf(q) >= 0 || tfn.indexOf(q) >= 0 || tfnln.indexOf(q) >= 0 || tlnfn.indexOf(q) >= 0) { 8211 results.results.push({ 8212 id : this.id, 8213 text : fn + ' ' + ln 8214 }); 8215 } 8216 }); 8217 8218 // the #to input will contain the ids: id1,id2,id3 8219 return results; 8220 } 8221 } 8222 }).on('change', function() { 8223 select2_memory[$(this).attr('id')] = $(this).select2('data'); 8224 8225 if ($(this).attr('id') == 'to') { 8226 select2_data = select2_memory[$(this).attr('id')]; 8227 select2_data_size = select2_data.length; 8228 } 8229 if ($(this).attr('id') == 'cc') { 8230 select2_data_cc = select2_memory[$(this).attr('id')]; 8231 select2_data_cc_size = select2_data_cc.length; 8232 } 8233 }); 8234 8235 if (select2_memory[recipient_type].length > 0) { 8236 el.data().select2.updateSelection(select2_memory[recipient_type]); 8237 8238 if (select2_data_size > 5) { 8239 setTimeout(function(){ 8240 add_sender_placeholder(select2_data, select2_data_size, '#s2id_to'); 8241 }, 100); 8242 } else if (select2_data_cc > 5) { 8243 setTimeout(function () { 8244 add_sender_placeholder(select2_data_cc, select2_data_cc_size, '#s2id_cc'); 8245 }, 100); 8246 } 8247 } 8248} 8249 8250// Auto suggest input also supporting arbitrary emails 8251 8252function autoSuggestEmailInit(element, selected_elems_size, selected_elems) { 8253 var el = $(element), results, preload_data, ln, fn, tln, tfn, tlnfn, tfnln, q; 8254 var select2_memory = []; 8255 8256 if (selected_elems != undefined && (selected_elems.length > 0)) { 8257 select2_memory = selected_elems; 8258 } 8259 8260 var max_selection_size = (select2_memory.length > 0 ? (select2_memory.length + 10) : 10); 8261 8262 el.select2({ 8263 multiple : true, 8264 maximumSelectionSize : max_selection_size, // for limitation of people number in the fields 8265 minimumInputLength : 2, // minimum chars to start the suggest query 8266 containerCssClass: 'select2-popup-input', 8267 ajax : { 8268 type : "GET", 8269 url : "/report/suggest_users_and_email", 8270 dataType : 'json', 8271 quietMillis : 500, // bigger delay before ajax is called 8272 data : function(term) { 8273 q = term; 8274 return { 8275 name : q 8276 }; 8277 }, 8278 results : function(data) { 8279 results = { 8280 results : [] 8281 }; 8282 preload_data = data.results; 8283 8284 $.each(preload_data, function() { 8285 ln = this.last_name; 8286 fn = this.first_name; 8287 tln = ln.toUpperCase(); 8288 tfn = fn.toUpperCase(); 8289 tfnln = tfn + ' ' + tln; 8290 tlnfn = tln + ' ' + tfn; 8291 8292 q = q.trim(); 8293 q = q.toUpperCase(); 8294 8295 if (tln.indexOf(q) >= 0 || tfn.indexOf(q) >= 0 || tfnln.indexOf(q) >= 0 || tlnfn.indexOf(q) >= 0) { 8296 if (ln.length > 0) { 8297 // It's an existing user 8298 results.results.push({ 8299 id : 'user|' + this.id, 8300 text : fn + ' ' + ln 8301 }); 8302 } else { 8303 // It's an email address 8304 results.results.push({ 8305 id : this.id, 8306 text : fn 8307 }); 8308 } 8309 } 8310 }); 8311 8312 return results; 8313 } 8314 } 8315 }).on('change', function() { 8316 select2_memory = $(this).select2('data'); 8317 select2_data = select2_memory; 8318 select2_data_size = select2_data.length; 8319 }); 8320 8321 if (select2_memory.length > 0) { 8322 el.data().select2.updateSelection(select2_memory); 8323 8324 if (select2_data_size > 5) { 8325 setTimeout(function() { 8326 add_sender_placeholder(select2_data, select2_data_size, '#s2id_send_to_emails'); 8327 }, 100); 8328 } 8329 } 8330} 8331 8332function popup_delete(element) { 8333 var url = $(element).attr('href'); 8334 var id = url.split('=')[1]; 8335 var extra = url.split('=')[0].split('?')[1]; 8336 var parent; 8337 8338 if (extra == 'message') { 8339 parent = '.messagesHolder'; 8340 } else { 8341 parent = '.notificationsHolder'; 8342 } 8343 8344 $.confirm({
8345 content : are_you_sure_text, 8346 confirm : function() { 8347 $.ajax({ 8348 type : "POST", 8349 url : url, 8350 complete : function() { 8351 var el = $(parent).find('.message-' + id); 8352 8353 if (el.length != 0) { 8354 el.remove(); 8355 } 8356 8357 $.facebox.close(); 8358 } 8359 }); 8360 } 8361 }); 8362 8363 return false; 8364} 8365 8366function scroll_to_bottom(element) { 8367 setTimeout(function() { 8368 var el = $(element).find('> h2').last(); 8369 8370 $(element).animate({ 8371 scrollTop : el.offset().top - 115 8372 }, 0); 8373 }, 50); 8374} 8375 8376// send message and replies using ajax 8377 8378function ajax_send(element) { 8379 var url = $('.messageSendPopup').parent('form').attr('action'); 8380 8381 if ((typeof(tinymce) == 'undefined') || (tinymce.get('popupContent') == null)) { 8382 var content = $('.messageSendPopup #popupContent').html(); 8383 } else { 8384 var content = tinymce.get('popupContent').getContent(); 8385 } 8386 8387 var obj = { 8388 url : url, 8389 data : { 8390 to : $('.messageSendPopup #to').val(), 8391 cc : $('.messageSendPopup #cc').val(), 8392 bcc : $('.messageSendPopup #bcc').val(), 8393 subject : $('.messageSendPopup #subject').val(), 8394 content : content, 8395 field : $('.messageSendPopup #field').val() 8396 } 8397 }; 8398 8399 ajax_send_message(obj, element); 8400 return false; 8401} 8402 8403function ajax_reply(element) { 8404 var url = $('.replyPopup').parent('form').attr('action').split('?'); 8405 8406 if ((typeof(tinymce) == 'undefined') || (tinymce.get('popupContent') == null)) { 8407 var content_container = $('.replyPopup #popupContent'); 8408 8409 if (content_container.is("textarea")) { 8410 var content = content_container.val(); 8411 } else { 8412 var content = content_container.html(); 8413 } 8414 } else { 8415 var content = tinymce.get('popupContent').getContent(); 8416 } 8417 8418 var obj = { 8419 url : url[0], 8420 data : { 8421 to : $('.replyPopup #to').val(), 8422 cc : $('.replyPopup #cc').val(), 8423 bcc : $('.replyPopup #bcc').val(), 8424 message : url[1].split('=')[1], 8425 subject : $('.replyPopup #subject').val(), 8426 content : content, 8427 reply_to_all : $('.replyPopup #reply-to-all').val(), 8428 ajax : true 8429 } 8430 }; 8431 8432 ajax_send_message(obj, element); 8433 return false; 8434} 8435 8436function ajax_reply_to_forum(element) { 8437 var url = $('.replyPopup').parents('form').attr('action').split('?'); 8438 8439 var obj = { 8440 url : url[0], 8441 data : { 8442 message : url[1].split('=')[1], 8443 notification : url[1].split('=')[1], 8444 content : tinymce.get('popupContent').getContent(), 8445 ajax : true 8446 } 8447 }; 8448 8449 ajax_send_message(obj, element); 8450 return false; 8451} 8452 8453function ajax_send_message(obj, element) { 8454 element.disabled = true; 8455 8456 $.ajax({ 8457 type : 'POST', 8458 url : obj.url, 8459 data : obj.data, 8460 dataType : 'json' 8461 }).done(function(data) { 8462 if (data.error) { 8463 element.disabled = false; 8464 const $popup = ($('body.evo').length ? $('.modal.is-open') : $('#facebox')); 8465 $popup.find('.alert_block.error').remove(); 8466 $popup.find('#alerts').after('<div class="alert_block error" role="alert"><div class="alert_flex"><div class="alert_icon"><i class="error inverted"></i></div><p>' + data.error + '</p><a href=""><i class="xCrossSmall"></i><span class="textOffScreen">Close alert</span></a></div></div>'); 8467 8468 } else { 8469 tinyPop = false; 8470 8471 if (select2_memory) { 8472 select2_memory.to = []; 8473 select2_memory.cc = []; 8474 select2_memory.bcc = []; 8475 $('.messageSendPopup #to').val(''); 8476 } 8477 8478 $.facebox.close(); 8479 8480 $('#centreColumn').find('> .info').remove(); 8481 $('#centreColumn').find('#alerts').after('<div class="alert_block info" role="alert"><div class="alert_flex"><div class="alert_icon"><i class="info inverted"></i></div><p>' + data.info + '</p><a href=""><i class="xCrossSmall"></i><span class="textOffScreen">Close alert</span></a></div></div>'); 8482 8483 // reset the fade_alert() interval 8484 clearInterval(closeAlertTimer); 8485 fade_alert(); 8486 8487 tinyPop = true; 8488 } 8489 }); 8490} 8491 8492function tinyMceFocusForce(editor_id) { 8493 var check_interval = setInterval(function() { 8494 if (tinymce.get(editor_id)) { 8495 tinymce.get(editor_id).focus(); 8496 clearInterval(check_interval); 8497 } 8498 }, 10); 8499} 8500 8501// notifications 8502 8503var notification_main_wrapper = '.notificationsPopUpHolder'; 8504var notifications_timer = null; 8505var notification_close_after = 5000; 8506var notifications_timer_cycles = 0; 8507var notifications_play_sound = false;
8508var notifications_close_arrow; 8509 8510function init_notifications_popup(sounds) { 8511 notifications_play_sound = sounds; 8512 8513 if(!is_mobile_app_mode()) { 8514 notifications_close_arrow = $(notification_main_wrapper).find('.notificationsBottom span'); 8515 notifications_click_outside(); 8516 8517 notifications_close_arrow.on('click', function (data) { 8518 $.each($(notification_main_wrapper).find('> div > ul li'), function () { 8519 $(this).animate({height: '0'}, 300, function () { 8520 $(this).remove(); 8521 notifications_hide_arrow(); 8522 }); 8523 }); 8524 }); 8525 } 8526} 8527 8528function notifications_click_outside() { 8529 $('html *').on('click', function(e) { 8530 if ($(this).hasClass('closeNotifications') || $(this).parent('span').hasClass('closeNotifications')) { 8531 $('.notificationsPopUpHolder').find('li').animate({'height' : '0'}, 300, function() { 8532 $(this).remove(); 8533 notifications_hide_arrow(); 8534 }); 8535 } 8536 8537 if (($(this).parents('.notificationsPopUpHolder').length == 1) || ($(this).parents('#facebox').length == 1)) { 8538 //e.stopPropagation(); 8539 } else { 8540 $('.notificationsPopUpHolder').find('li').animate({'height' : '0'}, 300, function() { 8541 $(this).remove(); 8542 notifications_hide_arrow(); 8543 }); 8544 } 8545 }); 8546} 8547 8548function notifications_listener(e) { 8549 var data = e.detail.data; 8550 8551 var messages = data.messages; 8552 var notifications = data.alerts; 8553 var new_messages = (messages && (messages.length > 0)); 8554 var new_notifications = (notifications && (notifications.length > 0)); 8555 var notifications_to_pop = []; 8556 var show_dropdown = false; 8557 8558 update_top_nav_counter(data.new_messages_count, '.messagesHolder', '.mobileMessagesHolder'); 8559 update_top_nav_counter(data.new_notifications_count, '.notificationsHolder', '.mobileNotificationsHolder'); 8560 8561 if (new_messages || new_notifications) { 8562 if (notifications_play_sound == true) { 8563 notifications_sound(); 8564 } 8565 8566 if (new_messages) { 8567 $.each(messages, function (key, value) { 8568 $('.notificationsPopUpHolder ul').append(notifications_html('message', value)); 8569 notifications_animate(notification_main_wrapper + ' .message-' + value.id); 8570 show_dropdown = true; 8571 }); 8572 } 8573 8574 if (new_notifications) { 8575 $.each(notifications, function (key, value) { 8576 if (value.popup == true) { 8577 notifications_to_pop.push(value); 8578 } else { 8579 $('.notificationsPopUpHolder ul').append(notifications_html('notification', value)); 8580 notifications_animate(notification_main_wrapper + ' .notification-' + value.id); 8581 show_dropdown = true; 8582 } 8583 }); 8584 } 8585 8586 if (show_dropdown == true) { 8587 $(notification_main_wrapper).find('.notificationsBottom').css('display', 'block'); 8588 } 8589 8590 notifications_popups(notifications_to_pop); 8591 8592 if (is_mobile_app_mode()) { 8593 send_header_to_app(); 8594 window.parent.postMessage('{"method": "notificationsPopup", "content": "1"}', '*'); 8595 } 8596 } 8597} 8598 8599function notifications_popups(notifications) { 8600 var stack = {}; 8601 8602 stack.className = 'vex-theme-os'; 8603 stack.initialDialogsClassName = 'vex-theme-os vex-theme-stack-demo'; 8604 8605 stack.advanceDemoDialogs = function () { 8606 var $remaining = $('.stack > .vex:not(".vex-closing")'); 8607 $('.stack').show(); 8608 $.each($remaining.removeClass('v0 v1 v2 v3 v4').toArray().reverse(), function (i, item) { 8609 $(item).addClass('v' + i); 8610 }); 8611 }; 8612 8613 $.each(notifications, function (index, notification) { 8614 $.ajax({ 8615 url: '/notifications/show', 8616 data: {small: true, popup: true, notification: notification.id}, 8617 dataType: 'html', 8618 async: false, 8619 success: function (html) { 8620 vex.dialog.alert({ 8621 appendLocation: '.stack', 8622 unsafeMessage: html, 8623 className: stack.initialDialogsClassName, 8624 callback: function (value) { 8625 setTimeout(function () { 8626 stack.advanceDemoDialogs(); 8627 }, 0); 8628 } 8629 }); 8630 window.focusTrap && focusTrap.deactivate(); 8631 8632 window.focusTrap && focusTrap.deactivate(); 8633 8634 stack.advanceDemoDialogs(); 8635 8636 var timer = 0; 8637 8638 $.each($($.parseHTML(html, document, true)).find('script'), function(index, value) { 8639 setTimeout(function() { 8640 if (value.src == '') { 8641 eval(value.text); 8642 } else { 8643 eval($.getScript(value.src)); 8644 } 8645 }, timer); 8646 8647 timer = timer + 100; 8648 }); 8649 8650 $(window).trigger('notificationLoaded'); 8651 } 8652 }); 8653 }); 8654} 8655 8656function notifications_html(type, notification) { 8657 var html = ''; 8658 var url; 8659 8660 if (type == 'notification') { 8661 url = '/notifications/show?popup=true&notification=' + notification.id; 8662 icon = 'signal3'; 8663 } else { 8664 url = '/inbox/show?popup=true&message=' + notification.id; 8665 icon = 'messages'; 8666 } 8667 8668 html += '<li class="ms-holder ' + type + '-' + notification.id + '" style="height: 57px;">'; 8669 html += '<a href="' + url + '" onclick="return popup_clicked(this);" role="button">'; 8670 html += '<span class="ms-image"><img src="' + notification.photo + '" width="30" height="30" alt=""></span>'; 8671 html += '<span class="ms-user">' + notification.first_name + ' ' + notification.last_name + '</span>'; 8672 html += (notification.class_name ? ' - <span class="ms-class-name">' + notification.class_name + '</span>' : ''); 8673 html += (notification.forum ? ' <span class="ms-arrow"></span> ' + notification.forum : ''); 8674 html += '<span class="ms-subject">' + notification.name + '</span>'; 8675 html += '<span class="ms-date">' + notification.date + '</span>'; 8676 html += '<span class="ms-status"><i class="' + icon + ' icnColor"></i></span>'; 8677 html += '</a>'; 8678 html += '</li>'; 8679 8680 return html; 8681} 8682 8683function notifications_animate(element) { 8684 var TimeOut; 8685 var height = '57px'; 8686 8687 $(element).animate({height: height}, 300); 8688 8689 TimeOut = setTimeout(function () { 8690 $(element).animate({height: '0'}, 300, function () { 8691 $(this).remove(); 8692 notifications_hide_arrow(); 8693 }); 8694 }, notification_close_after); 8695 8696 $(element).mouseout(function () { 8697 TimeOut = setTimeout(function () { 8698 $(element).animate({height: '0'}, 300, function () { 8699 $(this).remove(); 8700 notifications_hide_arrow(); 8701 }); 8702 }, notification_close_after); 8703 }); 8704 8705 $(element).mouseover(function () { 8706 clearTimeout(TimeOut); 8707 }); 8708} 8709 8710function notifications_hide_arrow() { 8711 if ($(notification_main_wrapper).find('> div > ul li').length == 0) { 8712 $(notification_main_wrapper).find('.notificationsBottom').hide(); 8713 } 8714} 8715 8716function notifications_sound() { 8717 if (self == top) { 8718 var sound = new Audio('/audio/notification-2.wav'); 8719 sound.play(); 8720 } else { 8721 window.parent.postMessage('{"method": "playNotificationSound", "src": "/audio/notification-2.wav"}', '*'); 8722 } 8723} 8724 8725function notification_mute() { 8726 var el = $('.audioNotifications'); 8727 var enable = el.data('enable'); 8728 8729 $.getJSON('/account/set_notifications_sound_enabled', {value: enable}, function (data) { 8730 if (data.status == 'ok') { 8731 if (enable == true) { 8732 el.data('enable', false); 8733 el.find('i').removeClass('audioOff').addClass('audioOn'); 8734 el.find('span.textOffScreen').html('Notification audio off'); 8735 notifications_play_sound = true; 8736 } else if (enable == false) { 8737 el.data('enable', true); 8738 el.find('i').removeClass('audioOn').addClass('audioOff'); 8739 el.find('span.textOffScreen').html('Notification audio on'); 8740 notifications_play_sound = false;
8741 } 8742 } 8743 }); 8744} 8745 8746function notification_mute_app(enable) { 8747 $.getJSON('/account/set_notifications_sound_enabled', {value: enable}, function (data) { 8748 if (data.status == 'ok') { 8749 if (enable == true) { 8750 notifications_play_sound = true; 8751 } else if (enable == false) { 8752 notifications_play_sound = false; 8753 } 8754 } 8755 }); 8756} 8757 8758// notifications counter 8759 8760function just_read_notification(id) { 8761 if (id) { 8762 update_unread_status_in_dd('.notificationsDropDown', id); 8763 } 8764 8765 update_unread_notifications(); 8766 notifications_arrow_navigation(); 8767} 8768 8769function update_unread_notifications() { 8770 $.getJSON('/notifications/get_unread_count', function(data) { 8771 update_top_nav_counter(data.count, '.notificationsHolder', '.mobileNotificationsHolder'); 8772 }); 8773} 8774 8775// messages counter 8776 8777function just_read_message(id) { 8778 if (id) { 8779 update_unread_status_in_dd('.messagesDropDown', id); 8780 } 8781 8782 update_unread_messages(); 8783 notifications_arrow_navigation(); 8784} 8785 8786function update_unread_messages() { 8787 $.getJSON('/inbox/get_unread_count', function(data) { 8788 update_top_nav_counter(data.count, '.messagesHolder', '.mobileMessagesHolder'); 8789 }); 8790} 8791 8792// update status icon in dropdowns 8793 8794function update_unread_status_in_dd(wrapper, id) { 8795 var dd = $(wrapper); 8796 var dd_is_open = dd.hasClass('dDownShow'); 8797 8798 if (dd_is_open === true) { 8799 var element = dd.find('#message-' + id).find('span.ms-status i'); 8800 8801 if (element.hasClass('xCross')) { 8802 element.removeClass('xCross').addClass('tick'); 8803 } 8804 } 8805} 8806 8807// notifications/messages popup navigation 8808var arrow_navig_usage = true; 8809 8810function notifications_arrow_navigation() { 8811 $(document).keydown(function(e) { 8812 switch(e.which) { 8813 case 37: // left 8814 if (arrow_navig_usage == true && $('#facebox .popup_left').length != 0 && $('#facebox .popup_left').is(':visible')) { 8815 $('#facebox .popup_left').trigger('click'); 8816 e.preventDefault(); 8817 8818 arrow_navig_usage = false; 8819 setTimeout(function() { arrow_navig_usage = true; }, 800); 8820 } 8821 break; 8822 8823 case 39: // right 8824 if (arrow_navig_usage == true && $('#facebox .popup_right').length != 0 && $('#facebox .popup_right').is(':visible')) { 8825 $('#facebox .popup_right').trigger('click'); 8826 e.preventDefault(); 8827 8828 arrow_navig_usage = false; 8829 setTimeout(function() { arrow_navig_usage = true; }, 800); 8830 } 8831 break; 8832 8833 default: return; // exit this handler for other keys 8834 } 8835 }); 8836} 8837 8838// counters 8839 8840function update_top_nav_counter(count, parent, mobile_parent) { 8841 var selector = $(parent); 8842 var mobile_selector = $(mobile_parent); 8843 8844 if (selector.length == 0) { 8845 return; // not found 8846 } 8847 8848 execute_update_top_nav_counter(count, selector); 8849 8850 if (mobile_selector.length == 0) { 8851 return; // not found 8852 } 8853 8854 execute_update_top_nav_counter(count, mobile_selector); 8855 8856 if (is_mobile_app_mode() && 8857 ( 8858 ( 8859 parent == '.messagesHolder' && 8860 (mobile_messages_count == 0 || count < mobile_messages_count) 8861 ) || ( 8862 parent == '.notificationsHolder' && 8863 (mobile_notifications_count == 0 || count < mobile_notifications_count) 8864 ) 8865 )) { 8866 switch (parent) { 8867 case '.messagesHolder': 8868 mobile_messages_count = count; 8869 break; 8870 case '.notificationsHolder': 8871 mobile_notifications_count = count; 8872 break; 8873 } 8874 send_header_to_app(); 8875 } 8876} 8877 8878function execute_update_top_nav_counter(count, selector) { 8879 var alert_el = selector.find('.newAlert'); 8880 var link_el = selector.find('> a:first-child'); 8881 8882 if (alert_el.length != 0) { 8883 var inline_count = parseInt(alert_el.text()); 8884 8885 if (inline_count != count) { 8886 if (count > 0) { 8887 alert_el.text(count.toString()); 8888 } else { 8889 alert_el.next('i').removeClass('messages').addClass('unread'); 8890 alert_el.remove(); 8891 } 8892 } 8893 } else { 8894 if (count > 0) { 8895 link_el.prepend('<span class="newAlert">' + count + '</span>').find('i').addClass('messages').removeClass('unread'); 8896 } 8897 } 8898} 8899 8900// mark as read 8901 8902function mark_all_as_read(controller, parent, mobile_parent) { 8903 $.confirm({ 8904 content : are_you_sure_text, 8905 confirm : function() { 8906 $.ajax({ 8907 type : "POST", 8908 url : "/" + controller + "/mark_all_as_read", 8909 dataType : "json", 8910 async : false, 8911 success : function(data) { 8912 if (data.status == 'done') { 8913 update_top_nav_counter(0, parent, mobile_parent); 8914 8915 $(parent).find('.dropDown li').each(function(index, value) { 8916 $(value).removeClass('ms-unread'); 8917 }); 8918 8919 $(parent).find('.markAllAsRead').hide(); 8920 } 8921 } 8922 }); 8923 } 8924 }); 8925} 8926 8927/** 8928 * ===================================================================== 8929 * ================================END================================== 8930 * ===================================================================== 8931 */ 8932 8933function set_back_link_url(url){ 8934 $('.backLink').attr('href', url); 8935} 8936 8937function init_portal_login() { 8938 $('#access_code_form').submit(function(e) { 8939 e.preventDefault(); 8940 $('#submit_access_code').click(); 8941 return false;
8942 }); 8943 8944 $('#submit_access_code').click(function(e) { 8945 $.post($('#access_code_form').attr('action'), $('#access_code_form').serialize(), function(data) { 8946 switch (data.status) { 8947 case 'submit': 8948 document.location = '/join_with_access_code/form?registration_code=' + encodeURIComponent($('#registration_code').val()); 8949 break; 8950 8951 case 'problem': 8952 $('#access_code_form').siblings('#alerts').html('<div class="alert_block error" style="width:auto" role="alert"><div class="alert_flex"><div class="alert_icon"><i class="error inverted"></i></div><p>' + data.text + '</p></div></div>').show(); 8953 break; 8954 } 8955 }); 8956 8957 return false; 8958 }); 8959 8960 $('#illini_btn, #saml2_btn, #clever_btn, #google_apps_btn, #sso_custom_btn, #office365_sso_btn, #oauth2_sso_btn').click(function(e){ 8961 e.preventDefault(); 8962 8963 var href = $(this).attr('href'); 8964 8965 // React Native WebView and regular browsers should just navigate normally 8966 if($(this).hasClass('is-mobile-app')){ 8967 if(window.ReactNativeWebView){ 8968 // React Native WebView - just navigate, the WebView will handle it 8969 document.location = href; 8970 } else if(window.parent !== window){ 8971 console.log('Legacy mobile app: sending postMessage'); 8972 window.parent.postMessage("{\"method\": \"loadBrowser\", \"href\": \""+href+"\", \"refresh_on_close\": \"1\"}", "*"); 8973 } else { 8974 // No mobile wrapper detected, just navigate normally 8975 console.log('No mobile wrapper: navigating to SSO'); 8976 document.location = href; 8977 } 8978 }else{ 8979 document.location = href; 8980 } 8981 8982 return false; 8983 }); 8984 8985 var switchForms = { 8986 container : $('[data-active_window]'), 8987 8988 config : { 8989 speed : 200 8990 }, 8991 8992 init : function() { 8993 $('[data-change_active]').on('click', this.toggleForm); 8994 }, 8995 8996 toggleForm : function(e) { 8997 changeButton = $(this); 8998 $('div.warning, div.info, div.error').remove(); 8999 9000 switchForms.container.each(function() { 9001 $this = $(this); 9002 // Find active change and show 9003 if ($this.data('active_window') == changeButton.data('change_active')) { 9004 $this.slideDown(switchForms.config.speed); 9005 $this.find('input[type="text"]').first().focus(); 9006 } else { 9007 $this.slideUp(switchForms.config.speed); 9008 } 9009 9010 }); 9011 9012 e.preventDefault(); 9013 } 9014 }; 9015 9016 switchForms.init(); 9017 9018 setTimeout(function() { 9019 focus_element('userid'); 9020 }, 0); 9021} 9022 9023function ajax_submit_login(login_submit_url, form_data) { 9024 var progress = add_progress($('#submit_button')); 9025 var progress_2fa = add_progress_2fa($('#two-factor-auth')); 9026 9027 $.support.cors = true; 9028 9029 $.ajax({ 9030 url: login_submit_url, 9031 data: form_data || $('#login_form').serialize(), 9032 dataType: 'json', 9033 method: 'post', 9034 success: function(data) { 9035 switch (data.status) { 9036 case 'redirect': 9037 document.location = data.url; 9038 break; 9039 9040 case 'html': 9041 $('#login_form').replaceWith(data.text); 9042 break; 9043 9044 case 'problem': 9045 $('#login_form').siblings('#alerts').html('<div class="alert_block error" style="width:auto" role="alert"><div class="alert_flex"><div class="alert_icon"><i class="error inverted"></i></div><p>' + data.text + '</p></div></div>').show(); 9046 var fields = $('#two-factor-auth').find('.input-list > input'); 9047 fields.val(""); 9048 fields.first().focus(); 9049 progress.stop(); 9050 progress_2fa.stop(); 9051 break; 9052 } 9053 }, 9054 error: function(x, t, m) { 9055 $('#login_form').siblings('#alerts').html('<div class="alert_block error" style="width:auto" role="alert"><div class="alert_flex"><div class="alert_icon"><i class="error inverted"></i></div><p>'+m+'</p></div></div>').show(); 9056 progress.stop(); 9057 progress_2fa.stop(); 9058 } 9059 }); 9060 9061 return false; 9062} 9063 9064/* Login popup stuff */ 9065 9066function request_password() { 9067 $('div.warning, div.info, div.error').remove(); 9068 9069 var email = $('#email').val(); 9070 var login = ''; 9071 9072 $.ajax({ 9073 type: "POST", 9074 url: "/log_in/request_password_ajax", 9075 data: {email: email}, 9076 dataType: "json", 9077 //async: false, // if is async it works. don't know the effect of enabling it, couldn't find any !!! 9078 success: function(data) { 9079 var info = data; 9080 9081 if ($('#simple_login').val() == 'true') { 9082 login = 'admin'; 9083 } else { 9084 login = 'credentials'; 9085 } 9086 9087 if (info.ok) { 9088 // this extra code adds a little animation effect
9089 $('.frmLogin[data-active_window="password"]').slideUp(200); 9090 $('.frmLogin[data-active_window="' + login + '"]').slideDown(200).prepend("<div class='info closeAlert keepopen' style='display:none'><p>" + info.message + "</p><a href=''></a></div>"); 9091 $('.frmLogin[data-active_window="' + login + '"] .info').delay(250).fadeIn(400); 9092 9093 $('.frmLogin[data-active_window="' + login + '"] .info > a').bind('click', function(e) { 9094 $(this).parent().animate({ 9095 height : '0', 9096 opacity : '0', 9097 margin : '0' 9098 }); 9099 9100 e.preventDefault(); 9101 }); 9102 } else { 9103 // this extra code adds a little animation effect 9104 $('.frmLogin[data-active_window="password"]').prepend("<div class='alert_block warning close_alert' style='display:none' role='alert'><div class='alert_flex'><div class='alert_icon'><i class='error inverted'></i></div><p>" + info.message + "</p><a href=''><i class='xCrossSmall'></i><span class='textOffScreen'>Close alert</span></a></div></div>"); 9105 $('.frmLogin[data-active_window="password"] .warning').fadeIn(400); 9106 9107 $('.frmLogin[data-active_window="password"] .warning > div > a').bind('click', function(e) { 9108 $(this).parent().parent().animate({ 9109 height : '0', 9110 opacity : '0', 9111 margin : '0' 9112 }); 9113 9114 e.preventDefault(); 9115 }); 9116 } 9117 }, 9118 error : function(request, status) { 9119 console.log(request); 9120 console.log(status); 9121 } 9122 }); 9123 9124 return false; 9125} 9126 9127// close popup function 9128function close_facebox_popup() { 9129 remove_close_button(); // if the autoclose is on we don't need close button anymore 9130 9131 setTimeout(function(){ 9132 $.facebox.close(); 9133 }, FACEBOX_CLOSING_TIME); 9134 9135} 9136 9137// remove the close from the facebox 9138function remove_close_button() { 9139 $('#facebox').find('a.close').remove(); 9140} 9141 9142function add_mobile_heading(heading, heading1_override) { 9143 if($(document.body).hasClass('evo')) return; 9144 var sub_header = $('.inline_tabs_options .tabnav .selected').clone().children().remove().end().text(); 9145 var mobile_page_heading = $('#mobile_page_heading'); 9146 if( !mobile_page_heading.closest('.inline_heading_tabs_options').length ) 9147 heading1_override = heading1_override.length ? heading1_override : sub_header; 9148 if ($('.pageHeading').length) { 9149 mobile_page_heading.html(heading); 9150 if(heading1_override.length){ 9151 mobile_page_heading.next().html(heading1_override); 9152 $('.pageHeading').addClass('switch_heading'); 9153 } 9154 } 9155 9156 // update page title based on heading as well 9157 var title = $('head title').text(); 9158 var titlePieces = title.split(' - '); 9159 if (titlePieces.length > 2) { 9160 $('head title').text(title.replace(titlePieces[1], heading)); 9161 } 9162} 9163 9164// alert 9165 9166function show_error(message) { 9167 var alerts = $('#alerts'); 9168 alerts.html('<div class="alert_block error close_alert" role="alert"><div class="alert_flex"><div class="alert_icon"><i class="error inverted"></i></div><p>' + message + '</p><a href=""><i class="xCrossSmall"></i><span class="textOffScreen">Close alert</span></a></div></div>'); 9169 alerts.show(); 9170 $('html, body').animate({scrollTop: 0}, 300); 9171} 9172 9173function show_warning(message) { 9174 var alerts = $('#alerts'); 9175 alerts.html('<div class="warning close_alert alert_block" role="alert"><div class="alert_flex"><div class="alert_icon"><i class="flag inverted"></i></div><p>' + message + '</p><a href=""><i class="xCrossSmall"><span class="textOffScreen">Close Alert</span></i></a></div></div>'); 9176 alerts.show(); 9177 $('html, body').animate({scrollTop: 0}, 300); 9178} 9179 9180function show_info(message) { 9181 var alerts = $('#alerts'); 9182 alerts.html('<div class="alert_block info close_alert" role="alert"><div class="alert_flex"><div class="alert_icon"><i class="error inverted"></i></div><p>' + message + '</p><a href=""><i class="xCrossSmall"></i><span class="textOffScreen">Close alert</span></a></div></div>'); 9183 alerts.show(); 9184 $('html, body').animate({scrollTop: 0}, 300); 9185} 9186 9187// add progress 9188 9189function add_progress(elem, options){ 9190 // disable button 9191 elem.attr('disabled','disabled').addClass('in-progress'); 9192 var opts = { 9193 lines: 11, // The number of lines to draw 9194 length: 4, // The length of each line 9195 width: 2, // The line thickness 9196 radius: 5, // The radius of the inner circle 9197 corners: 1, // Corner roundness (0..1) 9198 rotate: 0, // The rotation offset 9199 direction: 1, // 1: clockwise, -1: counterclockwise
9200 color: '#FFF', // #rgb or #rrggbb or array of colors 9201 speed: 1, // Rounds per second 9202 trail: 60, // Afterglow percentage 9203 shadow: false, // Whether to render a shadow 9204 hwaccel: false, // Whether to use hardware acceleration 9205 className: 'spinner', // The CSS class to assign to the spinner 9206 zIndex: 2e9, // The z-index (defaults to 2000000000) 9207 top: 'auto', // Top position relative to parent in px 9208 left: 'auto' // Left position relative to parent in px 9209 }; 9210 var spinner = new Spinner( $.extend(opts, options) ).spin(); 9211 var progress = { 9212 elem: elem, 9213 spinner: spinner, 9214 stop: function() { 9215 this.spinner.stop(); 9216 this.elem.removeAttr('disabled').removeClass('in-progress'); 9217 } 9218 }; 9219 elem.append(spinner.el); 9220 return progress; 9221} 9222 9223function add_progress_2fa(elem, options){ 9224 elem.addClass('in-progress'); 9225 var opts = { 9226 lines: 11, // The number of lines to draw 9227 length: 4, // The length of each line 9228 width: 2, // The line thickness 9229 radius: 5, // The radius of the inner circle 9230 corners: 1, // Corner roundness (0..1) 9231 rotate: 0, // The rotation offset 9232 direction: 1, // 1: clockwise, -1: counterclockwise 9233 color: '#282626', // #rgb or #rrggbb or array of colors 9234 speed: 1, // Rounds per second 9235 trail: 60, // Afterglow percentage 9236 shadow: false, // Whether to render a shadow 9237 hwaccel: false, // Whether to use hardware acceleration 9238 className: 'spinner', // The CSS class to assign to the spinner 9239 zIndex: 2e9, // The z-index (defaults to 2000000000) 9240 top: 'auto', // Top position relative to parent in px 9241 left: 'auto' // Left position relative to parent in px 9242 }; 9243 var spinner = new Spinner( $.extend(opts, options) ).spin(); 9244 var progress = { 9245 elem: elem, 9246 spinner: spinner, 9247 stop: function() { 9248 this.spinner.stop(); 9249 this.elem.removeClass('in-progress'); 9250 } 9251 }; 9252 elem.append(spinner.el); 9253 return progress; 9254} 9255 9256/* Payment processing popup for plans purchase */ 9257 9258function show_processing(message) { 9259 if ($('#facebox_overlay').length == 0) 9260 $('body').append('<div id="facebox_overlay" class="facebox_overlayBG fullscreen_progress"></div>'); 9261 $('.facebox_overlayBG').css('opacity','0.4'); 9262 9263 data = '<div class="header center"> \ 9264 <h2>' + processing + '</h2> \ 9265 </div> \ 9266 <div class="fullscreen_msg_content center"> \ 9267 <div class="spinner_holder mt5"></div> \ 9268 <p class="mb0">' + message + '<br>' + do_not_press_refresh_or_back_button + '</p> \ 9269 </div>'; 9270 9271 $('body').append('<div id="fullscreen_msg_holder" class="fullscreen_progress"><div id="fullscreen_msg" role="dialog" tabindex="-1"></div></div>'); 9272 $('#fullscreen_msg').html(data).focus(); 9273 var opts = { 9274 lines: 11, // The number of lines to draw 9275 length: 10, // The length of each line 9276 width: 4, // The line thickness 9277 radius: 13, // The radius of the inner circle 9278 corners: 1, // Corner roundness (0..1) 9279 rotate: 0, // The rotation offset 9280 direction: 1, // 1: clockwise, -1: counterclockwise 9281 color: '#5e5f5f', // #rgb or #rrggbb or array of colors 9282 speed: 1, // Rounds per second 9283 trail: 60, // Afterglow percentage 9284 shadow: false, // Whether to render a shadow 9285 hwaccel: false, // Whether to use hardware acceleration 9286 className: 'spinner', // The CSS class to assign to the spinner 9287 zIndex: 2e9, // The z-index (defaults to 2000000000) 9288 top: 'auto', // Top position relative to parent in px 9289 left: 'auto' // Left position relative to parent in px 9290 }; 9291 var spinner = new Spinner(opts).spin(); 9292 $('.spinner_holder').append(spinner.el); 9293 var fullscreen_progress = { 9294 stop: function() { 9295 $('.fullscreen_progress').remove(); 9296 } 9297 }; 9298 return fullscreen_progress; 9299} 9300 9301// over plan charges 9302 9303// note that "secure_protocol", host, etc. could be set once in lite.js during startup 9304 9305function pay_over_plan_charges(secure_protocol, current_host, ssl_host, message) { 9306 return secure_ajax_pay(secure_protocol, 'matrix_billing', 'submit_pay_over_plan_charges', 'payment_received', current_host, ssl_host, message); 9307} 9308 9309function start_plan_using_credit_card(secure_protocol, controller, current_host, ssl_host, message) { 9310 return secure_ajax_pay(secure_protocol, controller, 'create_credit_card', 'payment_plan_activated', current_host, ssl_host, message); 9311} 9312 9313function change_plan_using_credit_card(secure_protocol, controller, current_host, ssl_host, message) { 9314 return secure_ajax_pay(secure_protocol, controller, 'save_credit_card', 'payment_plan_changed', current_host, ssl_host, message); 9315} 9316 9317function change_credit_card(secure_protocol, controller, current_host, ssl_host, message) { 9318 return secure_ajax_pay(secure_protocol, controller, 'save_change_credit_card', 'credit_card_changed', current_host, ssl_host, message); 9319} 9320 9321function secure_ajax_pay(secure_protocol, controller, action, success_action, current_host, ssl_host, message, data, auth_token) { 9322 var fullscreen_progress; 9323 if (ssl_host.toUpperCase() == current_host.toUpperCase()) { 9324 $.ajax({ 9325 type : 'GET',
9326 data : data || $('#ecommerce_form').formSerialize(), 9327 url : secure_protocol + '://' + current_host + '/' + controller + '/' + action + (auth_token ? '?one_time_auth_token=' + auth_token : ''), 9328 dataType : 'jsonp', 9329 beforeSend: function(){ 9330 fullscreen_progress = show_processing(message); 9331 }, 9332 success : function(json, text_status, jqXHR) { 9333 if (json.error != null) { 9334 fullscreen_progress.stop(); 9335 show_error(json.error); 9336 } else { 9337 var stripe_card_error = ''; 9338 if (json.stripe_card_error) { stripe_card_error = '?stripe_card_error=true'} 9339 window.location.href = '/' + controller + '/' + success_action + stripe_card_error; 9340 } 9341 }, 9342 error : function(jqXHR, text_status, errorThrown) { 9343 fullscreen_progress.stop(); 9344 show_error(text_status); 9345 } 9346 }); 9347 } else { 9348 $.ajax({ 9349 type : 'GET', 9350 url : 'http://' + current_host + '/authentication/get_auth_token', 9351 dataType : 'jsonp', 9352 beforeSend: function(){ 9353 fullscreen_progress = show_processing(message); 9354 }, 9355 success : function(json, text_status, jqXHR) { 9356 secure_ajax_pay(secure_protocol, controller, action, success_action, ssl_host, ssl_host, message, data, json.auth_token); 9357 }, 9358 error : function(jqXHR, text_status, errorThrown) { 9359 fullscreen_progress.stop(); 9360 show_error(text_status); 9361 } 9362 }); 9363 } 9364 9365 return false; 9366} 9367 9368/* re-initialize checkboxes */ 9369function update_checkboxes() { 9370 $("input[type='checkbox']").each(function(index) { 9371 if (!$(this).next().is('label')) { 9372 $(this).after('<label for="' + $(this).attr('id') + '"></label>'); 9373 $(this).addClass("emptyLabel"); 9374 } 9375 }); 9376} 9377 9378/* tabs utility function */ 9379function tabs_selected_pointer(element, container, type, extra) { 9380 $(container+' .tabnav .tabnav__tab').removeClass('selected').attr("aria-selected","false").attr("tabindex","-1"); 9381 $(container+' div.tab-content').removeClass('active-tab').hide().attr("aria-hidden","true"); 9382 $(container+' #'+$(element).attr('rel')).show().addClass('active-tab').attr("aria-hidden","false"); 9383 $(element).addClass('selected').attr("aria-selected","true").attr("tabindex","0"); 9384 9385 if ( type == 'hc' ) { 9386 $('.facebox-content.help_centre').find('#hc_content_selector').remove(); 9387 $('.facebox-content.help_centre').find('#help_phrase').val(''); 9388 } else if ( type == 'pp' ) { 9389 if ( extra == true ){ 9390 $('.tabs-extra-class').show(); 9391 } else { 9392 $('.tabs-extra-class').hide(); 9393 } 9394 } 9395 9396 if ($('body').hasClass('catalog_class')) { 9397 resizeFixedLeftColumn(); 9398 } 9399 9400 $(element).parents('.dropDownHolder').find('.tabnav__toggle, [role="tab"]').first().removeClass('highlight'); 9401 $(element).parents('.dropDownHolder').find('.dropDown').removeClass('dDownShow'); 9402} 9403 9404// Moves the tabs from the dropdown to the nav so they can be adjusted again 9405// Legacy tabnav functions - DEPRECATED 9406// These functions are kept for backward compatibility but should not be used in new code. 9407// Use the new TabNav class instead. 9408 9409function reset_tabs(containerId) { 9410 TabNav.resetTabs(); 9411} 9412 9413function tabnav_adjustment(containerId) { 9414 TabNav.refresh(); 9415} 9416 9417/* help center */ 9418function open_tab() { 9419 $('#helpTabs a[rel="popup_help_center_overview"]').parent().next().children('a').trigger('click'); 9420} 9421 9422function hc_load_content_with_ajax(container) { 9423 var $this = $(container); 9424 var scroll = $this.find('.scroll'); 9425 var help_list = $this.find('.helpList a'); 9426 9427 $.each(help_list, function(index, value){ 9428 $(this).click(function(e){ 9429 e.preventDefault(); 9430 9431 var wrapper = $(this).parents('.tab-content'); 9432 var response = get_ajax_response($(this).attr('href'), 'html', false); 9433 var html = '<div id="hc_content_selector">' + response + '</div>'; 9434 9435 $('.facebox-content.help_centre').find('#hc_content_selector').remove(); 9436 9437 $(html).insertAfter(wrapper); 9438 9439 $('#hc_content_selector').height(wrapper.height()).find('.help_centre_content').height((wrapper.height() - $('.help_centre_heading').outerHeight())); 9440 9441 wrapper.hide(); 9442 9443 hc_content_links(); 9444 9445 $('.facebox-content.help_centre').find('#help_phrase').val(''); 9446 9447 isolatedScroll($('.help_centre_content')); 9448 }); 9449 }); 9450 9451 hc_help_for_page(); 9452 9453 hc_search_with_ajax(); 9454 9455 isolatedScroll(scroll); 9456} 9457 9458function hc_content_links() { 9459 $('img.imgL-blue').remove(); 9460 9461 $('a.back_to_list').click(function(e){ 9462 $('.facebox-content.help_centre').find('#hc_content_selector').remove(); 9463 $('.facebox-content.help_centre').find('#help_phrase').val(''); 9464 $('.active-tab').show(); 9465 }); 9466 9467 $.each($('#hc_content_selector a[href*="/help/"]'), function(index, value){ 9468 $(this).click(function(e){ 9469 e.preventDefault(); 9470 9471 var wrapper = $(this).parents('#hc_content_selector'); 9472 var response = get_ajax_response($(this).attr('href'), 'html', false); 9473 var html = '<div id="hc_content_selector">' + response + '</div>'; 9474 9475 $('.facebox-content.help_centre').find('#hc_content_selector').remove(); 9476 9477 $(html).insertAfter($('.facebox-content .active-tab')); 9478 9479 $('#hc_content_selector').height(wrapper.height()).find('.help_centre_content').height((wrapper.height() - $('.help_centre_heading').outerHeight())); 9480 9481 hc_content_links(); 9482 9483 $('.facebox-content.help_centre').find('#help_phrase').val(''); 9484 9485 isolatedScroll($('.help_centre_content')); 9486 }); 9487 }); 9488 9489 $('#hc_content_selector a[href*="#"]:not([href*="#help-"])').each(function(){ 9490 $(this).click(function(e){ 9491 e.preventDefault(); 9492 var link_name = $(this).attr('href').replace('#', ''); 9493 link_name = link_name.replace('%20', ' '); 9494 var scrollTop = $('#hc_content_selector a[name="'+link_name+'"]').position().top; 9495 $('.help_centre_content').scrollTop(scrollTop - 170); 9496 }); 9497 }); 9498} 9499 9500function hc_help_for_page() { 9501 var block = $('#popup_help_center_overview').find('.help_for_page'); 9502 9503 if (block.length != 0) { 9504 block.click(function(e){ 9505 e.preventDefault(); 9506 9507 var link = $(this).attr('href'); 9508 var section = link.split('?')[0].split('/')[2]; 9509 var topic = get_param_from_url(link, 'topic'); 9510 9511 $('#helpTabs a[rel="popup_help_center_' + section + '"]').trigger('click'); 9512 $('#popup_help_center_' + section).find('a[href="/help/' + section + '?topic=' + topic + '"]').trigger('click'); 9513 }); 9514 } 9515} 9516 9517function hc_go_to_topic($this) { 9518 if(typeof $this == "string"){ 9519 var link = $this; 9520 }else{ 9521 $($this).on('click', function(e) { e.preventDefault(); }); 9522 var link = $($this).attr('href'); 9523 } 9524 $.ajax({ 9525 type: 'GET',
9526 url: '/help', 9527 dataType: 'html', 9528 async: false, 9529 success: function(data) { 9530 $.facebox(data); 9531 var section = link.split('?')[0].split('/')[2]; 9532 var topic = get_param_from_url(link, 'topic'); 9533 $('#helpTabs a[rel="popup_help_center_' + section + '"]').trigger('click'); 9534 $('#popup_help_center_' + section).find('a[href="/help/' + section + '?topic=' + topic + '"]').trigger('click'); 9535 } 9536 }); 9537} 9538 9539function hc_search_with_ajax() { 9540 $('.facebox-content.help_centre').find('button[name="search_button"]').click(function(e){ 9541 e.preventDefault(); 9542 9543 var search_string = $(this).prev('input').val(); 9544 var search_name = $(this).prev('input').attr('name'); 9545 var wrapper = $('.help_centre'); 9546 var active = wrapper.find('.active-tab'); 9547 var response = get_ajax_response($(this).parents('form').attr('action') + '?' + search_name + '=' + search_string, 'html', false); 9548 var html = '<div id="hc_content_selector">' + response + '</div>'; 9549 9550 $('.facebox-content.help_centre').find('#hc_content_selector').remove(); 9551 9552 wrapper.append(html); 9553 9554 $('#hc_content_selector').height(active.height()).find('.help_centre_content').height((active.height() - $('.help_centre_heading').outerHeight())); 9555 9556 active.hide(); 9557 9558 hc_content_links(); 9559 9560 isolatedScroll($('.help_centre_content')); 9561 }); 9562} 9563 9564function hc_edit_ajax_submit(options) { 9565 $('.hc-edit').find('button[type="submit"]').on('click', function(e) { 9566 e.preventDefault(); 9567 9568 var form = $('.hc-edit'); 9569 var action = form.attr('action'); 9570 var content = tinymce.get('hc_content').getContent(); 9571 var saved = false; 9572 9573 $.ajax({ 9574 type: 'POST', 9575 url: action, 9576 data: {content: content}, 9577 dataType: 'json', 9578 async: false, 9579 success: function(data) { 9580 if (data.status == 'ok') { 9581 saved = true; 9582 } else { 9583 $.alert({content: options.error}); 9584 } 9585 } 9586 }); 9587 9588 if (saved == true) { 9589 var link = decodeURIComponent(action).split('?'); 9590 var topic = get_param_from_url('?'+link[2], 'topic'); 9591 var section = link[1].replace('from=/help/', '').replace('/', ''); 9592 9593 $('#helpTabs a[rel="popup_help_center_' + section + '"]').trigger('click'); 9594 $('#popup_help_center_' + section).find('a[href="/help/' + section + '?topic=' + topic + '"]').trigger('click'); 9595 } 9596 }); 9597} 9598 9599function help_hack_for_tinymce_correct_destroy(id) { 9600 if (id.indexOf('#') == 0) { 9601 id = id.substr(1); 9602 } 9603 9604 if (id.indexOf('.') == 0) { 9605 id = id.substr(1); 9606 } 9607 9608 if (typeof(tinymce) != 'undefined') { 9609 if (tinymce.get(id)) 9610 tinymce.get(id).destroy(); 9611 } 9612} 9613 9614function get_param_from_url(string, key, all) { 9615 var query = string.split("?")[1]; 9616 var data = (typeof query == 'undefined') ? [] : query.split("&"); 9617 var result = {}; 9618 for(var i=0; i<data.length; i++) { 9619 var item = data[i].split("="); 9620 result[item[0]] = item[1]; 9621 } 9622 if (all) { 9623 return result; 9624 } else { 9625 return result[key]; 9626 } 9627} 9628 9629function submit_classes_export(t, controller, action, age) { 9630 var t = $(t); 9631 var form = $('form#classes'); 9632 9633 form.attr('action', ('/' + controller + (action ? ('/' + action + (age ? '?age=' + age : '')) : ''))); 9634 9635 form.submit(); 9636} 9637 9638// tool provider edit form fields 9639 9640function show_tp_fields(t) { 9641 var t = $(t); 9642 var s = t.selected().val(); 9643 var w = t.parents('form').find('.domain-url-xml'); 9644 9645 if (s == 'URL') { 9646 w.find('label').first().text('Url:'); 9647 w.find('textarea').parent('p').show(); 9648 } else if (s == 'Domain') { 9649 w.find('label').first().text('Domain:'); 9650 w.find('textarea').parent('p').show(); 9651 } else if (s == 'URL/XML') { 9652 w.find('label').first().text('Url:'); 9653 w.find('textarea').parent('p').hide(); 9654 w.find('textarea').val(''); 9655 } else {
9656 $.alert({content: 'Not Good!'}); 9657 } 9658} 9659 9660// export more classes gradebook 9661 9662function check_checked(t) { 9663 var form = $(t).parents('form'); 9664 9665 if (form.length == 0) { 9666 form = $(".tableForm"); 9667 } 9668 9669 if (form.find('input[type="checkbox"]:checked').length > 0) { 9670 return true; 9671 } else { 9672 $.alert({content: 'Nothing selected. Select at least one item.'}); 9673 return false; 9674 } 9675} 9676 9677// tool info autocomplet when tool provider selected 9678 9679function handle_lti_version_data(select){ 9680 if(select.value === "LtiV1p3"){ 9681 $(".lti_v1p1_data").hide(); 9682 $(".lti_v1p3_data").show(); 9683 }else{ 9684 $(".lti_v1p1_data").show(); 9685 $(".lti_v1p3_data").hide(); 9686 } 9687} 9688 9689function do_tp_autofill(t,x, resource) { 9690 var tool_provider_id = t; 9691 var form = $('form#'+x); 9692 var resource = resource || 'resource'; 9693 9694 if (!tool_provider_id) { 9695 form.find('input#' + resource + '_name').val(''); 9696 form.find('textarea#' + resource + '_description').val(''); 9697 form.find('input#' + resource + '_config_url').val(''); 9698 $("#p_tool_public_key").hide(); 9699 $('#' + resource + '_tool_public_key').val(''); 9700 $('#' + resource + '_deployment_id').val(''); 9701 } else { 9702 get_tp_data(tool_provider_id, form, resource); 9703 } 9704} 9705 9706function get_tp_data(tool_provider_id, wrapper, resource) { 9707 $.ajax({ 9708 type: "POST", 9709 url: "/tool_provider/get_info/" + tool_provider_id, 9710 dataType: "json", 9711 success: function(data) { 9712 $.each(data, function(k,v) { 9713 wrapper.find('[id="' + resource + '_' + k + '"]').val(v); 9714 9715 if(k === 'lti_type' && v === 'LtiV1p3'){ 9716 $(".lti_v1p1_data").hide(); 9717 $(".lti_v1p3_data").show(); 9718 } 9719 if(k === 'lti_type' && v === 'Lti'){ 9720 $(".lti_v1p1_data").show(); 9721 $(".lti_v1p3_data").hide(); 9722 } 9723 }); 9724 } 9725 }); 9726} 9727 9728function launch_lti(t, controller) { 9729 var t = $(t); 9730 var id = t.attr('href').split('/')[3]; 9731 var url = decodeURIComponent(location.protocol + "//" + location.host + '/' + (controller || 'lti') + '/launch/' + id); 9732 var title = t.text(); 9733 var data = t.data(); 9734 9735 var w = data.width || '1000px'; 9736 var h = data.height || '800px'; 9737
9738 window.open(url, "'" + title + "'", "scrollbars=1, width=" + w + ", height=" + h); 9739} 9740 9741function custom_lti_launch(t, no_email) { 9742 if (no_email == true) { 9743 $.alert({content: 'You must first set your account email in profile settings!'}); 9744 return false; 9745 } 9746 9747 var t = $(t); 9748 var id = t.attr('href').replace( /^\D+/g, '').split('?')[0]; 9749 var url = location.protocol + "//" + location.host + '/assignment_lti/launch?assignment_id=' + id; 9750 var title = t.text(); 9751 9752 if(is_mobile_app_mode()){ 9753 window.parent.postMessage("{\"method\": \"loadBrowser\", \"href\": \"" + decodeURIComponent(url) + "\"}", "*"); 9754 }else{ 9755 window.open(decodeURIComponent(url), "'" + title + "'", "scrollbars=1,width=1000px,height=600px,resizable=true"); 9756 } 9757} 9758 9759function h5p_launch(t, no_email) { 9760 if (no_email == true) { 9761 $.alert({content: 'You must first set your account email in profile settings!'}); 9762 return false; 9763 } 9764 9765 var t = $(t); 9766 var id = t.attr('href').replace( /.+?\/show\//, '').split('?')[0]; 9767 var url = location.protocol + "//" + location.host + '/assignment_h5p/launch?assignment_id=' + id; 9768 var title = t.text(); 9769 9770 if(is_mobile_app_mode()){ 9771 window.parent.postMessage("{\"method\": \"loadBrowser\", \"href\": \"" + decodeURIComponent(url) + "\"}", "*"); 9772 }else{ 9773 window.open(decodeURIComponent(url), "'" + title + "'", "scrollbars=1,width=1000px,height=600px,resizable=true"); 9774 } 9775} 9776 9777function turnitin_launch(t, method, no_email, query) { 9778 if (no_email == true) { 9779 $.alert({content: 'You must first set your account email in profile settings!'}); 9780 return false; 9781 } 9782 9783 var t = $(t); 9784 var id = t.attr('href').replace( /^\D+/g, '').split('?')[0]; 9785 var url = location.protocol + "//" + location.host + '/turnitin_lti/launch?assignment_id=' + id; 9786 var title = t.text(); 9787 9788 url += "§ion=" + method; 9789 9790 if (query) { 9791 var query_size = Object.keys(query).length; 9792 9793 url += "&"; 9794 k = 1; 9795 9796 $.each(query, function(key, val) { 9797 url += key + "=" + val; 9798 url += (k < query_size ? '&' : ''); 9799 k++; 9800 }); 9801 } 9802 9803 if(is_mobile_app_mode()){ 9804 window.parent.postMessage("{\"method\": \"loadBrowser\", \"href\": \"" + decodeURIComponent(url) + "\"}", "*"); 9805 }else{ 9806 window.open(decodeURIComponent(url), "'" + title + "'", "scrollbars=1,width=1000px,height=600px,resizable=true"); 9807 } 9808} 9809 9810function check_turnitin_sync(class_id, assignment_id) { 9811 var interval = setInterval(function() { 9812 $.ajax({ 9813 type: 'POST', 9814 url: '/turnitin_lti/check_for_synchronization/' + class_id, 9815 data: {assignment_id: assignment_id}, 9816 dataType: 'json', 9817 async: false, 9818 success: function(json){ 9819 if (json.status == 'ok') { 9820 $('.sync-message').css('background-color', '#21A1B2').find('p').text(json.message); 9821 clearInterval(interval); 9822 setTimeout(function(){ location.reload(); }, 1500); 9823 } 9824 } 9825 }); 9826 }, 3000); 9827} 9828 9829function turnitin_forced_sync(el, id) { 9830 $.post("/teacher_turnitin_assignment/forced_sync", {id: id}); 9831 setTimeout(function(){ location.reload(); }, 700); 9832} 9833 9834function sync_sections(url){ 9835 $.post(url, $('#classes').serialize(), function(data){ 9836 $.facebox(data); 9837 }); 9838} 9839 9840function overwrite_box_with(max) { 9841 $("#facebox").css('max-width', max + 'px'); 9842 $("#facebox #faceboxContent").css('width', '100%'); 9843} 9844 9845// this is the filter search button show/hide engine 9846 9847function init_filter_effect(button, wrapper, extra, ajax) { 9848 button = (button || '.show-filter-field'); 9849 wrapper = (wrapper || '.compactFilterContainer'); 9850 extra = (extra || true); 9851 ajax = (ajax || false); 9852 9853 var $button = $(button); 9854 var $buttonParent = $button.parent(); 9855 // jQuery's .parent('li') returns an empty set when the parent isn't an 9856 // <li> (the action-toolbar case: button is a direct child of 9857 // .action-toolbar__group) -- fall back to the button itself so 9858 // show_filter_field/hide_filter_field get a real element either way. 9859 var search_button = $buttonParent.is('li') ? $buttonParent : $button; 9860 var filter_wrapper = $(wrapper); 9861 9862 if (ajax == true) { 9863 $.ajax({url: '/library/set_filter_session'}); 9864 } 9865 9866 if (search_button.is(":visible")) { 9867 show_filter_field(search_button, filter_wrapper, extra); 9868 } else { 9869 hide_filter_field(search_button, filter_wrapper, extra); 9870 } 9871 9872 if ($('input#compact_filter_phrase').length != 0) { 9873 focus_element('compact_filter_phrase'); 9874 } 9875} 9876 9877function show_filter_field(button, wrapper, extra) { 9878 if (!button.is('li')) { 9879 // action-toolbar: button is a direct child of .action-toolbar__group, 9880 // not wrapped in an <li> -- just hide it, no sibling border upkeep. 9881 button.hide(); 9882 } else if (button.parent().not(':only-child') && button.is(':only-child')) { 9883 button.parent().hide(); 9884 } else { 9885 button.hide(); 9886 9887 if (button.prev('li').length == 0) { 9888 button.next('li').css('border-left-width', '0'); 9889 } 9890 } 9891 9892 wrapper.show().find('input').focus(); 9893} 9894 9895function hide_filter_field(button, wrapper, extra) { 9896 var input = wrapper.hide().find('input'); 9897 9898 if (!button.is('li')) { 9899 button.show(); 9900 } else if (button.parent().not(':only-child') && button.is(':only-child')) { 9901 button.parent().show(); 9902 } else { 9903 button.show().next('li').css('border-left-width', '1px'); 9904 } 9905 9906 if (input.val() != '') { 9907 input.val('').keyup().blur(); 9908 } 9909 9910 if (extra == true) { 9911 var drop_downs = wrapper.find('select').not('#subject_filter'); 9912 var k = 0; 9913 9914 $.each(drop_downs, function(key,val) { 9915 k++; 9916
9917 $(val).find('option[value="0"]').attr("selected", "selected"); 9918 9919 if (k == drop_downs.length) { 9920 $(val).trigger('change'); 9921 } 9922 }); 9923 } 9924} 9925 9926function close_filter(url, button, wrapper, ajax) { 9927 var checkboxes = $(wrapper + ' input:checkbox:not(:checked)'); 9928 var name = $('input#compact_filter_phrase'); 9929 9930 if (ajax == true) { 9931 $.ajax({url: '/library/set_filter_session', async: false}); 9932 } 9933 9934 if (checkboxes.length > 0 || (name.length != 0 && name.val() != '')) { 9935 if (url.indexOf('library') !== -1) { 9936 url = removeUrlQueryParameter(window.location.href, 'name'); 9937 url = removeUrlQueryParameter(url, 'filter_active'); 9938 } 9939 window.location.href = url; 9940 } else { 9941 if ($(button).closest('ul').not(':only-child') && $(button).parent('li').is(':only-child')) { 9942 $(button).closest('ul').show(); 9943 } else { 9944 $(button).parent('li').show().next('li').css('border-left-width', '1px'); 9945 } 9946 9947 $(wrapper).hide(); 9948 } 9949} 9950 9951function removeUrlQueryParameter(url, paramKey) { 9952 return url 9953 .replace(new RegExp('[?&]' + paramKey + '=[^&#]*(#.*)?$'), '$1') 9954 .replace(new RegExp('([?&])' + paramKey + '=[^&]*&'), '$1'); 9955} 9956 9957function getUrlQueryParameter(url, name) { 9958 name = name.replace(/[\[]/, '\\[').replace(/[\]]/, '\\]'); 9959 var regex = new RegExp('[\\?&]' + name + '=([^&#]*)'); 9960 var results = regex.exec(url); 9961 return results === null ? '' : decodeURIComponent(results[1].replace(/\+/g, ' ')); 9962} 9963 9964// turnitin originality sync 9965// TODO: AT: Refactor the next to function for originality - if the refresh is kept !!! 9966 9967function do_turnitin_originality_sync_refresh(klass, assignment) { 9968 var pendings = $('#centreColumn').find('.originality-status-completed'); 9969 var error, error_count = 0; 9970 var synced = 0; 9971 9972 if (pendings.length > 0) { 9973 $('#centreColumn').find('#fixedSectionHeader').prepend('<div class="sync-message" style="width:auto;margin:1px 0 15px;background-color:#F4A30D;position:relative;padding:1px 10px;"><p><img src="/images/loading-16.gif" style="float:left;margin:2px 15px 0 0;" /> <span style="color:#fff;">Refreshing similarities report, for the users on this page, from Turnitin...</span></p></div>'); 9974 9975 resizeSectionHeader(); 9976 9977 var time = 1000; 9978 9979 $.each(pendings, function(k,v) { 9980 setTimeout(function(){ 9981 var pending = $(v); 9982 var paper_id = pending.data('paper'); 9983 var student_id = pending.data('student'); 9984 9985 $.ajax({ 9986 type: "POST", 9987 url: "/turnitin_lti/get_originality_status", 9988 data: {assignment_id: assignment, klass_id: klass, paper_id: paper_id, student_id: student_id}, 9989 dataType: 'json', 9990 success: function(data) { 9991 if (data.error) { 9992 error_count++; 9993 error = data.error; 9994 9995 $('.sync-message').css('background-color', '#C83131'); 9996 $('.sync-message').find('img').remove(); 9997 $('.sync-message span').html(error); 9998 9999 return false; 10000 } else { 10001 if (data.text == 'Pending') { 10002 $('span[data-student="' + data.student + '"]').html(data.text); 10003 } else { 10004 synced++; 10005 10006 $('span[data-student="' + data.student + '"]').html('<a href="' + assignment + '" class="tableLink2" onclick="turnitin_launch(this, \'originality\', false, {\'student\': ' + data.student + ', \'paperid\': ' + data.paper + '}); return false;">' + data.text + '</a>'); 10007 } 10008 } 10009 10010 if (error_count > 0) { 10011 return false; 10012 } 10013 10014 if ((error_count == 0) && (pendings.length == synced)) { 10015 $('.sync-message').css('background-color', '#21A1B2'); 10016 $('.sync-message').find('img').remove(); 10017 $('.sync-message span').html("Similarities successfully synchronized."); 10018 } 10019 } 10020 }); 10021 }, time); 10022 10023 time += 1000; 10024 }); 10025 } 10026} 10027 10028function do_turnitin_originality_sync(klass, assignment) { 10029 var pendings = $('#centreColumn').find('.pending-needs-sync'); 10030 var error, error_count = 0; 10031 var synced = 0; 10032 10033 if (pendings.length > 0) { 10034 $('#centreColumn').find('#fixedSectionHeader').prepend('<div class="sync-message" style="width:auto;margin:1px 0 15px;background-color:#F4A30D;position:relative;padding:1px 10px;"><p><img src="/images/loading-16.gif" style="float:left;margin:2px 15px 0 0;" /> <span style="color:#fff;">Fetching pending similarities from Turnitin...</span></p></div>'); 10035 10036 resizeSectionHeader(); 10037 10038 var synchronize_turnitin = function() { 10039 $.each(pendings, function() { 10040 var pending = $(this); 10041 var paper_id = pending.data('paper'); 10042 var student_id = pending.data('student'); 10043 10044 $.ajax({ 10045 type: "POST", 10046 url: "/turnitin_lti/get_originality_status", 10047 data: {assignment_id: assignment, klass_id: klass, paper_id: paper_id, student_id: student_id}, 10048 dataType: 'json', 10049 async: false, 10050 success: function(data) { 10051 if (data.error) { 10052 error_count++; 10053 error = data.error; 10054 10055 $('.sync-message').css('background-color', '#C83131'); 10056 $('.sync-message').find('img').remove(); 10057 $('.sync-message span').html(error); 10058 10059 return false;
10060 } else { 10061 if (data.text == 'Pending') { 10062 $('span[data-student="' + data.student + '"]').html(data.text); 10063 } else { 10064 synced++; 10065 10066 $('span[data-student="' + data.student + '"]').html('<a href="' + assignment + '" class="tableLink2" onclick="turnitin_launch(this, \'originality\', false, {\'student\': ' + data.student + ', \'paperid\': ' + data.paper + '}); return false;">' + data.text + '</a>'); 10067 } 10068 } 10069 } 10070 }); 10071 10072 if (error_count > 0) { 10073 return false; 10074 } 10075 }); 10076 10077 if ((error_count == 0) && (pendings.length == synced)) { 10078 $('.sync-message').css('background-color', '#21A1B2'); 10079 $('.sync-message').find('img').remove(); 10080 $('.sync-message span').html("Similarities successfully synchronized."); 10081 10082 clearInterval(interval); 10083 } 10084 }; 10085 10086 interval = setInterval(function(){ synchronize_turnitin(); }, 2500); 10087 } 10088} 10089 10090var check_submission_id = null; 10091var check_submission_student = null; 10092var check_submission_date = null; 10093 10094function check_for_submissions(id, student, date) { 10095 if ($('#lti_launch_frame').length > 0) { 10096 check_submission_id = id; 10097 check_submission_student = student; 10098 10099 if (date) { 10100 check_submission_date = date; 10101 } 10102 } 10103 10104 // WHY: match the launch functions by name, not the substring "submit". The 10105 // action toolbar renders these intercepted-click options as <button>s, and 10106 // its submit_form actions (Remove/Archive/...) carry submit_form_with_confirm 10107 // in their onclick -- a [onclick*="submit"] clause would bind those too and 10108 // poll for a submission that never happens. The list must name every launch 10109 // function used on a page that calls check_for_submissions: the legacy 10110 // [onclick*="h5p"] clause matched launch_lti only through its controller 10111 // argument ('assignment_h5p_v1p3'), which is not something to rely on. 10112 $('.optionsRibbon a[onclick*="submit"], .optionsRibbon a[onclick*="h5p"], ' + 10113 '.action-toolbar [onclick*="turnitin_launch"], .action-toolbar [onclick*="h5p_launch"], ' + 10114 '.action-toolbar [onclick*="custom_lti_launch"], .action-toolbar [onclick*="launch_lti"]').on('click', function(e){ 10115 check_for_submissions_implementation(id, student, date) 10116 }); 10117} 10118 10119function check_for_submissions_from_frame() { 10120 if (check_submission_date) { 10121 check_for_submissions_implementation(check_submission_id, check_submission_student, check_submission_date); 10122 } else { 10123 check_for_submissions_implementation(check_submission_id, check_submission_student); 10124 } 10125} 10126 10127function check_for_submissions_implementation(id, student, date) { 10128 var attempts = $('span.number-of-attempts'); 10129 var result; 10130 var query_string = window.location.search; 10131 var cycles = 60; 10132 var cycle = 0; 10133 var timer = 2000; 10134 10135 function check() { 10136 var time = setTimeout(function(){ 10137 $.ajax({ 10138 type: 'POST', 10139 url: '/assignment/check_for_submission/' + id, 10140 data: {student_id: student, date: date}, 10141 dataType: 'json', 10142 async: false, 10143 success: function(data) { 10144 result = parseInt(data.count); 10145 } 10146 }); 10147 10148 if ((parseInt(attempts.text()) < result) || (date && result > 0)) { 10149 if (query_string == '') { 10150 window.location = window.location.href + '?submitted=true'; 10151 } else if (query_string.indexOf('submitted=true') > -1) { 10152 window.location = window.location.href; 10153 } else { 10154 window.location = window.location.href + '&submitted=true'; 10155 } 10156 } 10157 10158 cycle++; 10159 10160 if (cycle <= cycles) { 10161 if ((timer < 7000) && (cycle % 3 == 0)) { 10162 timer += 500; 10163 } 10164 10165 check(); 10166 } 10167 }, timer); 10168 } 10169 10170 check(); 10171} 10172 10173function style_select_action() { 10174 $('select[name="klass[style]"]').on('change', function(){ 10175 var selected = $(this).find('option:selected').val(); 10176 10177 if (selected == 'Instructor' || selected == 'Blended') { 10178 show_element('duration'); 10179 hide_element('duration_text'); 10180 hide_element('duration_text textarea'); 10181 } else if (selected == 'Self paced' || selected == 'Micro class') { 10182 hide_element('duration'); 10183 show_element('duration_text'); 10184 show_element('duration_text textarea'); 10185 } 10186 }); 10187} 10188 10189function replace_relative_paths(string){ 10190 string = string.replace(/href="\//g, 'target="contentFrame" href="'+window.location.protocol+'//' + window.location.host + '/'); 10191 string = string.replace(/href='\//g, 'target=\'contentFrame\' href=\''+window.location.protocol+'//' + window.location.host + '/'); 10192 string = string.replace(/src="\//g, 'src="'+window.location.protocol+'//' + window.location.host + '/'); 10193 string = string.replace(/src='\//g, 'src=\''+window.location.protocol+'//' + window.location.host + '/'); 10194 string = string.replace(/action="\//g, 'target="contentFrame" action="'+window.location.protocol+'//' + window.location.host + '/'); 10195 string = string.replace(/action='\//g, 'target=\'contentFrame\' action=\''+window.location.protocol+'//' + window.location.host + '/'); 10196 10197 return string; 10198} 10199 10200function refresh_private_key(el) { 10201 $.confirm({
10202 content : 'Are you sure you want to reset your private key?', 10203 confirm : function() { 10204 $.ajax({ 10205 type : "POST", 10206 url : "/single_sign_on/refresh_private", 10207 dataType : "json", 10208 success : function(data) { 10209 $('#school_sso_custom_secret').val(data.key); 10210 } 10211 }); 10212 } 10213 }); 10214} 10215 10216function org_refresh_private_key(el, org_id) { 10217 $.confirm({ 10218 content : 'Are you sure you want to reset your private key?', 10219 confirm : function() { 10220 $.ajax({ 10221 type : "POST", 10222 url : "/org_single_sign_on/refresh_private/" + org_id, 10223 dataType : "json", 10224 success : function(data) { 10225 $('#sso_provider_sso_custom_secret').val(data.key); 10226 } 10227 }); 10228 } 10229 }); 10230} 10231 10232// resource library filtering 10233 10234function init_resource_library_filter(controller, action, id, lesson, section, folder, game, popup) { 10235 var name = $('#resource_name'); 10236 var subject = $('#resource_subject'); 10237 var classification = $('#resource_type'); 10238 var library = $('#resource_library'); 10239 var assignment_type = $('#resource_assignment_type'); 10240 10241 name.keyup(function(e) { 10242 typewatch(function() { resource_library_filter(controller, action, id, lesson, section, folder, game, popup, name, subject, classification, library); }, 1000); 10243 }); 10244 10245 subject.on('change', function(e) { 10246 resource_library_filter(controller, action, id, lesson, section, folder, game, popup, name, subject, classification, library, assignment_type); 10247 }); 10248 10249 classification.on('change', function(e) { 10250 resource_library_filter(controller, action, id, lesson, section, folder, game, popup, name, subject, classification, library, assignment_type); 10251 }); 10252 10253 library.on('change', function(e) { 10254 resource_library_filter(controller, action, id, lesson, section, folder, game, popup, name, subject, classification, library, assignment_type); 10255 }); 10256 10257 assignment_type.on('change', function(e) { 10258 resource_library_filter(controller, action, id, lesson, section, folder, game, popup, name, subject, classification, library, assignment_type); 10259 }); 10260} 10261 10262function resource_library_filter(controller, action, id, lesson, section, folder, game, popup, name, subject, classification, library, assignment_type) { 10263 var wrapper = $("#ResourceLibraryFilterWrapper"); 10264 var url = '/' + controller + '/' + action + (id ? '/' + id : '') + '?'; 10265 var args = []; 10266 10267 if (tool_to_edit_id) { 10268 args.push('tool_to_edit_id=' + tool_to_edit_id); 10269 } 10270 10271 if (base_controller) { 10272 args.push('base_controller=' + base_controller); 10273 } 10274 10275 if (select_all_learners) { 10276 args.push('select_all=' + select_all_learners); 10277 } 10278 10279 if (stacked_picker) { 10280 args.push('stacked_picker=' + stacked_picker); 10281 } 10282 10283 if (copilot_picker) { 10284 args.push('copilot_picker=' + copilot_picker); 10285 args.push('copilot_callback=' + copilot_callback); 10286 } 10287 10288 if (select_learners) { 10289 args.push(select_learners); 10290 } 10291 10292 if (name) { 10293 args.push('resource_name=' + encodeURIComponent(name.val())); 10294 } 10295 10296 if (lesson) { 10297 args.push('lesson_id=' + lesson); 10298 } 10299 10300 if (section) { 10301 args.push('section_id=' + section); 10302 } 10303 10304 if (folder) { 10305 args.push('folder=' + folder); 10306 } 10307 10308 if (game) { 10309 args.push('game=' + game); 10310 } 10311 10312 if (subject) { 10313 var value = subject.val(); 10314 10315 if (value) { 10316 args.push('subject=' + value); 10317 } 10318 } 10319 10320 if (classification) { 10321 var value = classification.val(); 10322 10323 if (value) { 10324 args.push('classification=' + value); 10325 } 10326 } 10327 10328 if (library) { 10329 var value = library.val(); 10330 10331 if (value) { 10332 args.push('library=' + value); 10333 } 10334 } 10335 10336 if (assignment_type) { 10337 var value = assignment_type.val(); 10338 10339 if (value) { 10340 args.push('assignment_type=' + value); 10341 } 10342 } 10343 10344 args.push('ajax=true'); 10345 url += args.join('&'); 10346 10347 $.ajax({ 10348 type: "POST", 10349 url: url, 10350 dataType: 'html', 10351 beforeSend: function(){ 10352 ajax_add_loader(wrapper, true); 10353 }, 10354 success: function(html) { 10355 wrapper.find('.content').html(html); 10356 close_ajax_loader(); 10357 10358 if (wrapper.find('.facebox-content').length == 1) { 10359 isolatedScroll(wrapper.find('.facebox-content')); 10360 } 10361 } 10362 }); 10363} 10364 10365function ajax_add_loader(container, remove_footer_height) { 10366 container.css('position', 'relative'); 10367 10368 if ($('#AppendedLoader').length == 0) { 10369 if (container.find('.footer').length >= 1 && !remove_footer_height) { 10370 container.append('<div id="AppendedLoader" style="position:absolute; z-index: 5; top:0; left: 0; background: rgba(255, 255, 255, 0.8) url(\'/images/loading-animation-' + (is_grey_page_mode() ? 'grey' : 'white') + '-retina.gif\') no-repeat center center / 100px; width: 100%; height: ' + (container.height() - container.find('.footer').height()) + 'px;"></div>'); 10371 } else {
10372 container.append('<div id="AppendedLoader" style="position:absolute; z-index: 5; top:0; left: 0; background: rgba(255, 255, 255, 0.8) url(\'/images/loading-animation-' + (is_grey_page_mode() ? 'grey' : 'white') + '-retina.gif\') no-repeat center center / 100px; width: 100%; height: ' + container.height() + 'px;"></div>'); 10373 } 10374 } 10375} 10376 10377function close_ajax_loader() { 10378 if ($('#AppendedLoader').length >= 1) { 10379 $('#AppendedLoader').remove(); 10380 } 10381} 10382 10383/* type watch */ 10384var typewatch = (function(){ 10385 var time = 0; 10386 10387 return function(callback, ms){ 10388 clearTimeout (time); 10389 time = setTimeout(callback, ms); 10390 }; 10391})(); 10392 10393// Infinite scroll for add existing 10394 10395var infinite_stop; 10396var infinite_pause; 10397 10398function init_add_existing(count, limit, controller, action, id, subject, name, library, classification, lesson_id) { 10399 if (count > limit) { 10400 infinite_stop = false; 10401 infinite_pause = true; 10402 10403 init_add_existing_infinite_scroll(controller, action, id, subject, name, library, classification, lesson_id); 10404 } 10405 10406 add_existing_submit_button(); 10407} 10408 10409// lesson_id is hack, replace with container_id 10410 10411function init_add_existing_infinite_scroll(controller, action, id, subject, name, library, classification, lesson_id) { 10412 $("#facebox .facebox-content, .modal.is-open .facebox-content").scroll(function() { 10413 if (infinite_pause) { 10414 if ($(this).scrollTop() >= ($(this)[0].scrollHeight - $(this).height() - 50)) { 10415 infinite_pause = false; 10416 add_existing_more(controller, action, id, subject, name, library, classification, lesson_id); 10417 } 10418 } 10419 }); 10420} 10421 10422function add_existing_more(controller, action, id, subject, name, library, classification, lesson_id) { 10423 let wrapper = $('#facebox .facebox-content').last(); 10424 if (wrapper.length === 0) { 10425 wrapper = $('.modal.is-open .facebox-content').last(); 10426 } 10427 let more = $('.add-existing-more').last(), 10428 offset = more.data('offset'), 10429 limit = more.data('limit'), 10430 size = more.data('size'), 10431 count = more.data('count'), 10432 url = '/' + controller + '/' + action + (id ? '/' + id : ''); 10433 10434 url += '?'; 10435 url += 'offset=' + (offset + limit); 10436 url += '&limit=' + limit; 10437 url += '&count=' + count; 10438 10439 if (tool_to_edit_id){ 10440 url += '&tool_to_edit_id=' + tool_to_edit_id; 10441 } 10442 10443 if (stacked_picker){ 10444 url += '&stacked_picker=' + stacked_picker; 10445 } 10446 10447 if (copilot_picker){ 10448 url += '&copilot_picker=' + copilot_picker; 10449 url += '&copilot_callback=' + copilot_callback; 10450 } 10451 10452 if (base_controller){ 10453 url += '&base_controller=' + base_controller; 10454 } 10455 10456 if (lesson_id && lesson_id.length > 0) { 10457 url += '&lesson_id=' + lesson_id; 10458 } 10459 10460 if (subject && subject.length > 0) { 10461 url += '&subject=' + subject; 10462 } 10463 10464 if (name && name.length > 0) { 10465 url += '&resource_name=' + name; 10466 } 10467 10468 if (library && library.length > 0) { 10469 url += '&library=' + library; 10470 } 10471 10472 if (classification && classification.length > 0) { 10473 url += '&classification=' + classification; 10474 } 10475 10476 if (!infinite_stop) { 10477 $.ajax({ 10478 type: "POST", 10479 url: url, 10480 beforeSend: function(){ 10481 more.append('<img src="/images/loading-animation-white-retina.gif" width="100" />'); 10482 }, 10483 success: function(data) { 10484 more.remove(); 10485 infinite_pause = true; 10486 10487 wrapper.append(data); 10488 10489 add_existing_submit_button(); 10490 10491 var results_count = $('.add-existing-more').last().data('size'); 10492 10493 if (results_count == 0) { 10494 infinite_pause = false; 10495 infinite_stop = true; 10496 10497 $('.add-existing-more').text('No more results'); /* translate */ 10498 } 10499 } 10500 }); 10501 } 10502} 10503 10504function add_existing_submit_button() { 10505 // support for multi-select 10506 $("#ResourceLibraryFilterWrapper").find('input[type="checkbox"]').on('change', function(){ 10507 var count = $("#ResourceLibraryFilterWrapper").find('input[type="checkbox"]:checked').length; 10508 toggle_selector_submit_button(count > 0); 10509 }); 10510 10511 // support for single-select 10512 $("#ResourceLibraryFilterWrapper").find('input[type="radio"]').on('change', function(){ 10513 var count = $("#ResourceLibraryFilterWrapper").find('input[type="radio"]:checked').length; 10514 toggle_selector_submit_button(count > 0); 10515 }); 10516} 10517 10518function toggle_selector_submit_button(value) { 10519 if (value) { 10520 $('#ResourceLibraryFilterWrapper .footer button').removeAttr('disabled'); 10521 $('#ResourceLibraryFilterWrapper .footer button').removeAttr('style'); 10522 } else { 10523 $('#ResourceLibraryFilterWrapper .footer button').attr('disabled', 'disabled').css('background-color', '#aeaeae'); 10524 } 10525} 10526 10527// game 10528 10529function game_settings_display() { 10530 var leaderboard = $('#game_leaderboard'); 10531 var leaderboard_wrapper = $('.leaderboardSettings'); 10532 10533 leaderboard.on('change', function() { 10534 if (this.checked) { 10535 leaderboard_wrapper.show(); 10536 } else { 10537 leaderboard_wrapper.hide(); 10538 } 10539 }); 10540} 10541 10542function update_game_display_count(controller, the_id, game_id) { 10543 $('#game_display_count').on('change', function() { 10544 ajax_request('/' + controller + '/set_leaderboard_count/' + the_id + '?game=' + game_id + '&value=' + this.value); 10545 }); 10546} 10547 10548function popup_player_history(selector, admin_controller, id, the_id) { 10549 var selector = $(selector); 10550 10551 selector.on('click', function() { 10552 $.facebox({'ajax' : '/' + admin_controller + '/player/' + the_id + '?game=' + id + '&player_id=' + $(this).data('id')}); 10553 }); 10554} 10555 10556function popup_team_history(selector, admin_controller, id, the_id) { 10557 var selector = $(selector); 10558 10559 selector.on('click', function() { 10560 $.facebox({'ajax' : '/' + admin_controller + '/team/' + the_id + '?game=' + id + '&team_id=' + $(this).data('id')}); 10561 }); 10562} 10563 10564function toggle_select_choice(element) { 10565 var selector = $(element); 10566 var parent = selector.parents('p'); 10567 var value = selector.val().toLowerCase().replace(/ /g, '_'); 10568 10569 if (value == 'immediately') { 10570 parent.find('span').hide(); 10571 } else { 10572 parent.find('span:not(.time_wrap)').hide(); 10573 parent.find('span:not(.time_wrap)').find('select').val(''); 10574 parent.find('span:not(.time_wrap)').find('input').val(''); 10575 parent.find('.' + value).show(); 10576 } 10577} 10578 10579// deselect the action from the commit 10580
10581function deselect_sync_action(el, sync_id) { 10582 $.ajax({ 10583 type: 'POST', 10584 url: '/sis/select_action/', 10585 data: {action_id: $(el).val(), sync_id: sync_id, value: $(el).is(':checked')}, 10586 success: function(data) { 10587 console.log(data); 10588 }, 10589 error: function(data) { 10590 console.log(data); 10591 } 10592 }); 10593} 10594 10595/* dashboard calendar */ 10596 10597var smallCalendarNav = null; 10598 10599function init_small_calendar_keyboard() { 10600 var $wrapper = $('.calendar-small-wrapper'); 10601 if ($wrapper.length === 0) return; 10602 10603 // Ensure all day links are not focusable by default (only via navigation mode) 10604 $wrapper.find('td a').attr('tabindex', '-1'); 10605 10606 smallCalendarNav = new CalendarKeyboardNav({ 10607 container: $wrapper[0], 10608 containerSelector: '.calendar-small-wrapper', 10609 navigationType: 'grid', 10610 editMode: false, 10611 10612 getInitialCell: function() { 10613 var $target = $wrapper.find('td.current'); 10614 if ($target.length === 0) { 10615 $target = $wrapper.find('td').first(); 10616 } 10617 return $target; 10618 }, 10619 10620 onEnterNav: function() { 10621 var $target = this.getInitialCell(); 10622 var $link = $target.find('a'); 10623 if ($link.length) { 10624 $link.attr('tabindex', '0').focus(); 10625 var $cell = $link.closest('td'); 10626 this.currentRow = parseInt($cell.attr('data-row')) || 0; 10627 this.currentCol = parseInt($cell.attr('data-col')) || 0; 10628 } 10629 }, 10630 10631 onExitNav: function() { 10632 $wrapper.find('td a').attr('tabindex', '-1'); 10633 $wrapper.focus(); 10634 }, 10635 10636 getCellSelector: function(row, col) { 10637 return $wrapper.find('td[data-row="' + row + '"][data-col="' + col + '"]'); 10638 }, 10639 10640 onActivateCell: function($current) { 10641 var $cell = $current.is('td') ? $current : $current.closest('td'); 10642 if ($cell.length) { 10643 var $link = $cell.find('a'); 10644 if ($link.length) { 10645 window.location.href = $link.attr('href'); 10646 } 10647 } 10648 } 10649 }); 10650 10651 // Override focusCell to focus the link inside the td 10652 var originalFocusCell = smallCalendarNav.focusCell.bind(smallCalendarNav); 10653 smallCalendarNav.focusCell = function($cell) { 10654 if (!$cell || $cell.length === 0) return; 10655 10656 $wrapper.find('td a').attr('tabindex', '-1'); 10657 10658 var $link = $cell.is('a') ? $cell : $cell.find('a'); 10659 if ($link.length) { 10660 $link.attr('tabindex', '0').focus(); 10661 } 10662 10663 var $td = $cell.is('td') ? $cell : $cell.closest('td'); 10664 this.currentRow = parseInt($td.attr('data-row')) || 0; 10665 this.currentCol = parseInt($td.attr('data-col')) || 0; 10666 10667 this.scrollIntoView($link.length ? $link : $cell); 10668 }; 10669} 10670 10671function get_dashboard_calendar(month, year, day) { 10672 $.get('/my_calendar/month_small/?year=' + year + '&month=' + month + (typeof day != 'undefined' ? '&day=' + day : ''), function(data) { 10673 $('#small_calendar_container').html(data); 10674 $('.small-month-name').html($('#new_small_month_name').val()); 10675 init_small_calendar_keyboard(); 10676 }); 10677 10678 $('#previous_small_calendar_link').attr('href', 'javascript:get_dashboard_calendar(' + (month == 1 ? 12 : month - 1) + ', ' + (month == 1 ? year - 1 : year) + ')'); 10679 $('#next_small_calendar_link').attr('href', 'javascript:get_dashboard_calendar(' + (month == 12 ? 1 : month + 1) + ', ' + (month == 12 ? year + 1 : year) + ')'); 10680 10681 // update aria labels for the arrows for accessibility 10682 var previous_month = new Date(); 10683 previous_month.setMonth((month == 1 ? 12 : month - 1) - 1) 10684 previous_month = previous_month.toLocaleString('en-US', { month: 'short' }); 10685 var previous_year = (month == 1 ? year - 1 : year); 10686 10687 document.getElementById('previous_small_calendar_link').ariaLabel = previous_month + " " + previous_year; 10688
10689 var next_month = new Date(); 10690 next_month.setMonth((month == 12 ? 1 : month + 1) - 1) 10691 next_month = next_month.toLocaleString('en-US', { month: 'short' }); 10692 var next_year = (month == 12 ? year + 1 : year); 10693 10694 document.getElementById('next_small_calendar_link').ariaLabel = next_month + " " + next_year; 10695} 10696 10697/* x_api_servers */ 10698function set_current_x_api_server(x_api_id) { 10699 ajax_request('/x_api_servers/set_default/' + x_api_id); 10700} 10701 10702function try_connection(x_api_server_id) { 10703 $.ajax({ 10704 url : '/x_api_servers/try_connection/' + x_api_server_id, 10705 type : 'post', 10706 success : function(data) { 10707 console.log(data); 10708 }, 10709 error: function (xhr, ajaxOptions, thrownError) { 10710 console.log('Fail'); 10711 } 10712 }); 10713} 10714 10715/* sis filter */ 10716function sis_filter_schools(el) { 10717 var selected_value = $(el).find('option:selected').val(); 10718 var location = window.location.href; 10719 10720 if (location.match(/\?./)) { 10721 location = location.split("?")[0]; 10722 } 10723 10724 if (selected_value) { 10725 window.location = location + '?school_id=' + selected_value; 10726 } else { 10727 window.location = location; 10728 } 10729} 10730 10731function validateZoomUSCredentials(apiKey, apiSecret) { 10732 $.ajax({ 10733 url : '/zoomus/validate_account_credentials/', 10734 type : 'post', 10735 data : { 10736 key : apiKey, 10737 secret : apiSecret 10738 }, 10739 10740 success : function(data) { 10741 if(data['status'] == true) { 10742 $(".zoomus-apikeys-submit-form ").off('submit').submit(); 10743 } else { 10744 alert(data['status']); 10745 } 10746 }, 10747 10748 error: function (xhr, ajaxOptions, thrownError) { 10749 // Error 10750 } 10751 }); 10752} 10753 10754function validateWebExCredentials(apiKey, apiSecret, site_name) { 10755 $.ajax({ 10756 url : '/webex/validate_account_credentials/', 10757 type : 'post', 10758 data : { 10759 key : apiKey, 10760 secret : apiSecret, 10761 site : site_name 10762 }, 10763 10764 success : function(data) { 10765 if(data['status'] == true) { 10766 $(".webex-apikeys-submit-form").off('submit').submit(); 10767 } else { 10768 alert(data['status']); 10769 } 10770 }, 10771 10772 error: function (xhr, ajaxOptions, thrownError) { 10773 // Error 10774 } 10775 }); 10776} 10777 10778$(document).ready(function() { 10779 $(".zoomus-apikeys-submit-form").submit(function(event) { 10780 apiKey = $('#zoomus_account_consumer_key').val(); 10781 apiSecret = $('#zoomus_account_consumer_secret').val(); 10782 10783 validateZoomUSCredentials(apiKey, apiSecret); 10784 event.preventDefault(); 10785 }); 10786 10787 $(".webex-apikeys-submit-form").submit(function(event) { 10788 apiKey = $('#webex_account_consumer_key').val(); 10789 apiSecret = $('#webex_account_consumer_secret').val(); 10790 site_name = $('#webex_account_site_name').val(); 10791 10792 validateWebExCredentials(apiKey, apiSecret, site_name); 10793 event.preventDefault(); 10794 }); 10795}); 10796 10797// display "student_access" option if "Personal" library is NOT checked # in application_helper/edit_library 10798 10799function update_scope_user_student_access(radio_button) { 10800 if (radio_button.checked) { 10801 $('.student_access_library').hide(); 10802 } 10803} 10804 10805 function update_scopes_student_access(radio_button) { 10806 if (radio_button.checked) { 10807 $('.student_access_library').show(); 10808 } 10809 } 10810 10811function select_current_theme(controller, radio_button, id) { 10812 if (radio_button.checked) { 10813 if (id == null) { 10814 window.location.href = '/' + controller + '/select_current_theme?theme_id=' + radio_button.value; 10815 } else { 10816 window.location.href = '/' + controller + '/select_current_theme/' + id + '?theme_id=' + radio_button.value; 10817 } 10818 } 10819} 10820 10821function select_current_accessible_theme(controller, radio_button, id) { 10822 if (radio_button.checked) { 10823 if (id == null) { 10824 window.location.href = '/' + controller + '/select_current_accessible_theme?theme_id=' + radio_button.value; 10825 } else { 10826 window.location.href = '/' + controller + '/select_current_accessible_theme/' + id + '?theme_id=' + radio_button.value; 10827 } 10828 } 10829} 10830 10831function set_accessibility_theme(controller, checkbox, id) { 10832 if (id == null) { 10833 window.location.href = '/' + controller + '/set_accessibility_theme?value=' + check_s(checkbox); 10834 } else { 10835 window.location.href = '/' + controller + '/set_accessibility_theme/' + id + '?value=' + check_s(checkbox); 10836 } 10837} 10838 10839function clear_errors() { 10840 $('#facebox div.error').remove(); 10841 $('div.block div.error').remove(); 10842} 10843 10844// disable submit button unless checkbox is checked. used mostly for agree terms and conditions. 10845var toggle_submit_button = function(el){ 10846 $('form').find(':button[type=submit]').attr('disabled', !el.checked); 10847}; 10848 10849// disable submit button unless all checkboxes are checked. used mostly for agree terms and conditions. 10850var toggle_submit_button2 = function(total_policies){ 10851 var checked_number = $('input[name="terms[]"]:checked').length; 10852 $('form').find(':button[type=submit]:not(.policy-consent-accept)').attr('disabled', (checked_number != total_policies)); 10853}; 10854 10855function switch_test_variable(element) { 10856 if ($(element).is(':checked')) { 10857 window.location.href = '/testing_support/list?' + $(element).attr('id') + '=true'; 10858 } else { 10859 window.location.href = '/testing_support/list?' + $(element).attr('id') + '=false'; 10860 } 10861} 10862 10863// Get bankcode based on card type as per payubiz documentation. 10864function watch_bankcode() { 10865 $('#ccnum').on('change', function() {
10866 bankcode = detectCardType($(this).val()); 10867 $('#bankcode').val(bankcode); 10868 }); 10869 10870 function detectCardType(number) { 10871 number = $.trim(number); 10872 var re = { 10873 CC: /^4[0-9]{12}(?:[0-9]{3})?$|^5[1-5][0-9]{14}$/, // visa or master card 10874 AMEX: /^3[47][0-9]{13}$/, // american_express 10875 DINR: /^3(?:0[0-5]|[68][0-9])[0-9]{11}$/ // diners 10876 }; 10877 10878 for (var key in re) { 10879 if (re[key].test(number)) { 10880 return key 10881 } 10882 } 10883 } 10884} 10885 10886function show_credit_card_block(flag) { 10887 if (flag) { 10888 $('#payu_biz_cc_block').show(); 10889 } else { 10890 $('#payu_biz_cc_block').hide(); 10891 } 10892} 10893 10894function payu_biz_sync_cc_names() { 10895 $('#user_first_name').blur(function() { 10896 if ($('#firstname').length > 0) { 10897 $('[id="firstname"]').val(this.value); 10898 } 10899 }); 10900 $('#user_last_name').blur(function() { 10901 if ($('#lastname').length > 0) { 10902 $('[id="lastname"]').val(this.value); 10903 } 10904 }); 10905 $('#user_email').blur(function() { 10906 if ($('#email').length > 0) { 10907 $('[id="email"]').val(this.value); 10908 } 10909 }); 10910} 10911 10912// tabs 10913 10914function init_draggable_tabs(object_id, tabs_controller) { 10915 $("#tab_list").sortable({ 10916 handle : 'td.draggable_handle', 10917 update : function(event, ui) { 10918 var tab_ids = $('#tab_list tr').map( function() { return $(this).attr('data-tab_id'); } ).toArray(); 10919 window.location.href = '/' + tabs_controller + '/update_tabs_order/' + object_id + '?tab_ids=' + tab_ids.join(','); 10920 } 10921 }); 10922 10923 $("#tab_list").disableSelection(); 10924} 10925 10926function set_tab(item_id, tabs_controller, checkbox) { 10927 window.location.href = '/' + tabs_controller + '/set_tab/' + item_id + '?attribute=' + checkbox.value + '&value=' + (checkbox.checked ? 'true' : 'false'); 10928} 10929 10930function set_start_tab(item_id, checkbox) { 10931 window.location.href = '/class_configure/set_start_tab/' + item_id + '?attribute=' + checkbox.value + '&value=' + (checkbox.checked ? 'true' : 'false'); 10932} 10933 10934function init_draggable_profile_tabs() { 10935 $("#tab_list").sortable({ 10936 handle : 'td.draggable_handle', 10937 update : function(event, ui) { 10938 var tab_ids = $('#tab_list tr').map( function() { return $(this).attr('data-tab_id'); } ).toArray(); 10939 window.location.href = '/profile_tabs/update_tabs_order?tab_ids=' + tab_ids.join(','); 10940 } 10941 }); 10942 10943 $("#tab_list").disableSelection(); 10944} 10945 10946function nospaces(t){ 10947 if(t.value.match(/\s/g)){ 10948 t.value=t.value.replace(/\s/g,''); 10949 } 10950} 10951 10952// return card type based on credit card (paypal pro). 10953function watch_card_type() { 10954 $('#credit_card_number').on('change', function () { 10955 cardtype = detectCardTypePaypalPro($(this).val()); 10956 $('#credit_card_card_type').val(cardtype); 10957 }); 10958} 10959 10960function detectCardTypePaypalPro(number) { 10961 number = $.trim(number); 10962 var re = { 10963 visa: /^4[0-9]{12}(?:[0-9]{3})?$/, 10964 mastercard: /^5[1-5][0-9]{14}$/, 10965 amex: /^3[47][0-9]{13}$/, 10966 discover: /^6(?:011|5[0-9]{2})[0-9]{12}$/ 10967 }; 10968 10969 for (var key in re) { 10970 if (re[key].test(number)) { 10971 return key 10972 } 10973 } 10974} 10975 10976function isNumberKey(evt){ 10977 var charCode = (evt.which) ? evt.which : evt.keyCode; 10978 if (charCode > 31 && (charCode < 48 || charCode > 57)) 10979 return false; 10980 return true; 10981} 10982 10983function numericOnly() { 10984 $(".numericOnly").bind('keypress', function (e) { 10985 if (e.keyCode == '9' || e.keyCode == '16') { 10986 return; 10987 } 10988 var code; 10989 if (e.keyCode) code = e.keyCode; 10990 else if (e.which) code = e.which; 10991 if (e.which == 46) 10992 return true; 10993 if (code == 8 || code == 46) 10994 return true; 10995 if (code < 48 || code > 57) 10996 return false; 10997 } 10998 ); 10999 $(".numericOnly").bind("paste", function (e) { 11000 e.preventDefault(); 11001 }); 11002 $(".numericOnly").bind('mouseenter', function (e) { 11003 var val = $(this).val(); 11004 if (val != '0') { 11005 val = val.replace(/[^0-9.]+/g, ""); 11006 $(this).val(val); 11007 } 11008 }); 11009} 11010 11011// Toggle switch 11012function toggle_the_switch(element, toggle_elements){ 11013 $(toggle_elements).toggle(); 11014 $(element).parent().siblings('span').toggleClass('selected'); 11015} 11016 11017// grading scale changed 11018 11019function update_max_score(select) { 11020 if ($('#assignment_max_score').length > 0) { 11021 var selected_points = $(select.options[select.selectedIndex]).attr('data-points'); 11022 if (selected_points.length > 0) { 11023 $('.max-info').show(); 11024 $('#assignment_max_score').hide(); 11025 $('#assignment_max_score').val(parseInt(selected_points)); 11026 } else { 11027 $('.max-info').hide(); 11028 $('#assignment_max_score').show(); 11029 } 11030 } 11031} 11032 11033// comment thread 11034 11035function grading_save_thread_comment(id, student_id, peer_id, result_id, origin, gradebook) { 11036 var textarea = $('.grading-thread-comment-textarea #comment'); 11037 var gradebook_check = gradebook || false; 11038 var editor = tinyMCE.get($(textarea).attr('id')); 11039 var content = editor.getContent(); 11040 11041 if (isStringEmpty(content)) { 11042 $.alert({content: "The comment can't be empty"}); 11043 } else { 11044 var data = {student_id: student_id, peer_id: peer_id, content: content, origin: origin, gradebook: gradebook_check}; 11045 11046 if (result_id != false) { 11047 data.result_id = result_id; 11048 grading_save_comment(id, data, editor); 11049 } else { 11050 $.ajax({ 11051 url: '/teacher_assignment/get_result_id/' + id, 11052 data: {student: student_id}, 11053 async: false, 11054 success: function (response) { 11055 if (response.result_id != false) { 11056 data.result_id = response.result_id; 11057 } 11058 11059 grading_save_comment(id, data, editor); 11060 } 11061 }); 11062 } 11063 } 11064} 11065 11066function grading_save_comment(id, data, editor) { 11067 $.ajax({ 11068 type: 'POST', 11069 url: '/comment_thread/save/' + id, 11070 data: data, 11071 async: false, 11072 success: function(response) { 11073 if (response.status == 'bad') { 11074 $.alert({content: response.message}); 11075 } else { 11076 $('.grading-thread-comment-list').append(response); 11077 editor.setContent(''); 11078 editor.isNotDirty = 1; 11079 } 11080 } 11081 }); 11082} 11083 11084function grading_comment_thread_events(id, gradebook) { 11085 var active = false;
11086 var gradebook_check = gradebook || false; 11087 11088 $('.grading-thread-comment-list').on('click', function(e) { 11089 var el = $(e.target); 11090 var comment_wrapper = el.parents('.comment'); 11091 var comment_id = comment_wrapper.data('id'); 11092 var content_wrapper = comment_wrapper.find('.content'); 11093 var content = content_wrapper.html(); 11094 11095 if (el.hasClass('delete')) { 11096 if (active == true) { 11097 return false; 11098 } 11099 11100 $.confirm({ 11101 content: "Do you really want to delete this comment?", 11102 confirm: function() { 11103 var comment_wrapper = el.parents('.comment'); 11104 var comment_id = comment_wrapper.data('id'); 11105 11106 $.post('/comment_thread/delete/' + id, {comment: comment_id}, function(response) { 11107 if (response.status == 'ok') { 11108 comment_wrapper.remove(); 11109 } else { 11110 $.alert({content: response.message}); 11111 } 11112 }); 11113 } 11114 }); 11115 } 11116 11117 if (el.hasClass('edit')) { 11118 if (active == true) { 11119 return false; 11120 } 11121 11122 var textarea = $('.grading-thread-comment-textarea #comment'); 11123 var editor = tinyMCE.get($(textarea).attr('id')); 11124 editor.remove(); 11125 $(textarea).hide(); 11126 $('p.grading-thread-comment-options').hide(); 11127 11128 $.ajax({ 11129 type: 'POST', 11130 url: '/comment_thread/edit/' + id, 11131 data: {comment: comment_id}, 11132 dataType: 'html', 11133 success: function(html) { 11134 content_wrapper.html('').html(html + '<div class="update-options alignR"><a href="javascript:void(0)" class="ml10 inline-update">Update</a><a href="javascript:void(0)" class="ml10 inline-cancel">Cancel</a></div>'); 11135 // workaround FF tinymce editor issue 11136 if(typeof reinit_tinymce_editor !== 'undefined' && typeof reinit_tinymce_editor === 'function'){ 11137 reinit_tinymce_editor(comment_id); 11138 } 11139 } 11140 }); 11141 11142 active = true; 11143 } 11144 11145 if (el.hasClass('inline-update')) { 11146 var editor = tinyMCE.get($('#comment_text_' + comment_id).attr('id')); 11147 content = editor.getContent(); 11148 11149 var option_directionality = editor.options.get('directionality'); 11150 var option_language = editor.options.get('language'); 11151 var option_height = editor.options.get('height'); 11152 11153 if (content.trim() == '') { 11154 $.alert({content: "The comment can't be empty"}); 11155 } else { 11156 $.post('/comment_thread/update/' + id, {comment: comment_id, content: content, gradebook: gradebook_check}, function(response) { 11157 if (response.status == 'bad') { 11158 $.alert({content: response.message}); 11159 comment_thread_get_original(id, comment_id, editor, comment_wrapper, gradebook_check) 11160 } else { 11161 editor.remove(); 11162 comment_wrapper.html(response); 11163 11164 $('.grading-thread-comment-textarea #comment').show(); 11165 $('p.grading-thread-comment-options').show(); 11166 tinyMCEenable("#comment", option_directionality, option_height, option_language, ""); 11167 } 11168 11169 active = false; 11170 }); 11171 } 11172 } 11173 11174 if (el.hasClass('inline-cancel')) { 11175 var editor = tinyMCE.get($('#comment_text_' + comment_id).attr('id')); 11176 11177 var option_directionality = editor.options.get('directionality'); 11178 var option_language = editor.options.get('language'); 11179 var option_height = editor.options.get('height'); 11180 11181 comment_thread_get_original(id, comment_id, editor, comment_wrapper, gradebook_check); 11182 active = false; 11183 11184 var textarea = $('.grading-thread-comment-textarea #comment'); 11185 $(textarea).show(); 11186 $('p.grading-thread-comment-options').show(); 11187 tinyMCEenable("#comment", option_directionality, option_height, option_language, ""); 11188 } 11189 }); 11190} 11191 11192function comment_thread_get_original(id, comment_id, editor, wrapper, gradebook) { 11193 var gradebook_check = gradebook || false; 11194 11195 $.ajax({ 11196 type: 'POST', 11197 url: '/comment_thread/get_original/' + id, 11198 data: {comment: comment_id, gradebook: gradebook_check}, 11199 dataType: 'html', 11200 success: function(response) { 11201 editor.remove(); 11202 wrapper.html(response); 11203 } 11204 }); 11205} 11206 11207/* rubric points ordering*/ 11208function set_rubric_points_ordering(order) { 11209 ajax_request('/standard_grading_scales/set_rubric_points_ordering?rubric_points_ordering=' + order ); 11210} 11211 11212/* validate user email fields */ 11213function validateEmail(email) { 11214 var re = /^(([^<>()[\]\\.,;:\s@\"]+(\.[^<>()[\]\\.,;:\s@\"]+)*)|(\".+\"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/; 11215 return re.test(email.trim()); 11216} 11217 11218function validatePassword(password) { 11219 if (typeof strong_password_regex == 'undefined' || typeof school_strong_passwords == 'undefined') { 11220 return true; 11221 } 11222 11223 if (school_strong_passwords) { 11224 return strong_password_regex.test(password); 11225 } else { 11226 return password.length >= regular_password_min_chars; 11227 } 11228} 11229 11230function remove_validation_error(el) { 11231 $('label[for=' + el.id + ']').find('i.error').remove(); 11232 $(el).removeAttr('aria-invalid'); 11233 $('#' + el.id + '_error_msg').remove(); 11234} 11235 11236function validate_and_show_error(el) { 11237 var el_val = $(el).val().trim(); 11238 if ((el_val != '') && !validateEmail(el_val)) { 11239 display_validation_error(el, 'Please enter a valid email'); 11240 } else { 11241 remove_validation_error(el); 11242 } 11243} 11244 11245function display_validation_error(el, text) { 11246 remove_validation_error(el); 11247 11248 // Add error icon with tooltip 11249 $('label[for=' + el.id + ']').append("<i class='error icnColor floatR mr0' id='"+ el.id +"_tippy'></i>"); 11250 $(el).attr('aria-invalid', 'true'); 11251 tippy('#' + el.id + '_tippy', { 11252 content: text, 11253 arrow: true, 11254 theme: 'error', 11255 maxWidth: '350px', 11256 placement: (is_rtl_mode() ? 'top-start' : 'top-end'),
11257 allowHTML: false 11258 }); 11259 11260 // Add visible error message below the field 11261 var errorMsg = $('<div class="validation-error-message" id="' + el.id + '_error_msg" role="alert" aria-live="polite"><i class="error"></i> ' + text + '</div>'); 11262 $(el).after(errorMsg); 11263} 11264 11265function validate_and_show_error_user_email(el) { 11266 validate_and_show_error(el); 11267 11268 var ec_el = document.getElementById('user_email_confirmation'); 11269 var ec_el_val = $(ec_el).val().trim(); 11270 var el_val = $(el).val().trim(); 11271 11272 if (el_val === '') { 11273 $(ec_el).val(''); 11274 remove_validation_error(ec_el); 11275 }else if (ec_el_val.toLowerCase() !== el_val.toLowerCase()) { 11276 if (ec_el_val === '') { 11277 display_validation_error(ec_el, 'Please enter a valid email'); 11278 }else { 11279 display_validation_error(ec_el, 'Email and Confirm email does not match'); 11280 } 11281 } 11282} 11283 11284function validate_and_show_error_user_email_confirmation(el) { 11285 validate_and_show_error(el); 11286 11287 var el_val = $(el).val().trim(); 11288 11289 if ((el_val !== '') && validateEmail(el_val) && (el_val.toLowerCase() !== $('#user_email').val().trim().toLowerCase())) { 11290 display_validation_error(el, 'Email and Confirm email does not match'); 11291 } 11292} 11293 11294function validate_user_email_and_confirmation() { 11295 validate_and_show_error_user_email(document.getElementById('user_email')); 11296 validate_and_show_error_user_email_confirmation(document.getElementById('user_email_confirmation')); 11297} 11298 11299function validate_and_show_error_user_password(el) { 11300 var pswc_el = document.getElementById('user_password_confirmation'); 11301 11302 if ($(el).val() === '' || validatePassword($(el).val())) { 11303 remove_validation_error(el); 11304 } 11305 11306 if ($(el).val() === '') { 11307 $(pswc_el).val(''); 11308 remove_validation_error(pswc_el); 11309 } else if (!validatePassword($(el).val())) { 11310 display_validation_error(el, 'Please enter a valid password'); 11311 } else if ($(pswc_el).val() !== $(el).val()) { 11312 if ($(pswc_el).val() === '') { 11313 display_validation_error(pswc_el, 'Please enter a valid password'); 11314 } else { 11315 display_validation_error(pswc_el, 'Password and Confirm password does not match'); 11316 } 11317 } 11318} 11319 11320function validate_and_show_error_user_password_confirmation(el) { 11321 if ($(el).val() === '') { 11322 display_validation_error(el, 'Please enter a valid password'); 11323 }else if ($(el).val() !== $('#user_password').val()) { 11324 display_validation_error(el, 'Password and Confirm password does not match'); 11325 }else { 11326 remove_validation_error(el); 11327 } 11328} 11329 11330function validate_user_password_and_confirmation() { 11331 validate_and_show_error_user_password(document.getElementById('user_password')); 11332 validate_and_show_error_user_password_confirmation(document.getElementById('user_password_confirmation')); 11333} 11334 11335$(document).ready(function() { 11336 $(document).on('keyup', '#user_email, #user_email_confirmation', function() { 11337 validate_user_email_and_confirmation(); 11338 }); 11339 11340 $(document).on('keyup', '#user_password, #user_password_confirmation', function() { 11341 validate_user_password_and_confirmation(); 11342 }); 11343 11344 $(document).on('keyup', '#user_sms_email', function() { 11345 validate_and_show_error(this); 11346 }); 11347}); 11348 11349// Disable submit button until all required fields are filled. 11350 11351function validate_user_signup_form(fields, form_id, submit_btn) { 11352 11353 submit_btn.attr('disabled', 'disabled'); 11354 var email_fields = ['email','email_confirmation','sms_email']; 11355 11356 if( $('#user_country').length) { 11357 $('#user_country').bind('change', function() { 11358 if ($(this).val() == 'United States' || $(this).val() == 'Brazil') { 11359 $.each( fields, function(i, e) { if( e == 'other_state' ) fields[i] = 'state'; } ); 11360 } 11361 else { 11362 $.each( fields, function(i, e) { if( e == 'state' ) fields[i] = 'other_state'; } ); 11363 } 11364 }); 11365 } 11366 if ($('#user_other_state_div').is(':visible')) { 11367 $.each( fields, function(i, e) { if( e == 'state' ) fields[i] = 'other_state'; } ); 11368 } 11369 11370 $('form#'+ form_id).find('[id^=user_],input[id="organization"],input[name="terms[]"]').bind("change keyup", function() { 11371 11372 var empty = false; 11373 $.each( fields, function( i, v ) { 11374 if ((v == 'state') || (v == 'other_state')) { 11375 if (($('input#user_' + v).val() == '') || ($('select#user_' + v).val() == '')) { 11376 empty = true; 11377 } 11378 } else { 11379 // organization field 11380 if (v == 'organization') { 11381 if ($('#user_organization_id').val() == 'other') { 11382 empty = $('form#' + form_id +' #' + v).val() == ''; 11383 } else { 11384 empty = $('#user_organization_id').val() == ''; 11385 } 11386 } else { 11387 if (($('#user_' + v).val() == '') || ($('form#'+ form_id +' #'+ v).val() == '')) { 11388 empty = true; 11389 } 11390 } 11391 } 11392 11393 // confirmation fields 11394 if (($('#user_' + v + '_confirmation').length > 0)) { 11395 if (v == 'email') { 11396 var confirmation_is_equal = ($('#user_email_confirmation').val().trim().toLowerCase() == $('#user_email').val().trim().toLowerCase()); 11397 } else { 11398 var confirmation_is_equal = ($('#user_' + v + '_confirmation').val().trim() == $('#user_' + v).val().trim()); 11399 } 11400 if ($('#user_' + v + '_confirmation').val() == '' || !confirmation_is_equal) { 11401 empty = true; 11402 } 11403 } 11404 11405 // date fields 11406 if (($('#user_' + v + '_1i').length > 0) && (($('#user_' + v + '_1i').val() == '') || ($('#user_' + v + '_2i').val() == '') || ($('#user_' + v + '_3i').val() == ''))) { 11407 empty = true; 11408 } 11409 }); // fields - each 11410 11411 $.each( email_fields, function( i, v ) { 11412 if (($('#user_' + v).length > 0) && ($('#user_' + v).val() != '') && !validateEmail($('#user_' + v).val())) { 11413 empty = true; 11414 } 11415 }); // email_fields - each 11416 11417 // password strength validation 11418 if (!validatePassword($('#user_password').val())) { 11419 empty = true; 11420 } 11421 11422 var checked_terms = $('input[name="terms[]"]:checked').length; 11423 var total_terms = $('input[name="terms[]"]').length; 11424 11425 if( !empty && ((total_terms == 0) || (checked_terms == total_terms)) ) 11426 submit_btn.removeAttr('disabled'); 11427 else 11428 submit_btn.attr('disabled', 'disabled'); 11429 }); // keyup 11430} 11431 11432/* message form */ 11433 11434function show_extra_field_in_message_form(elem, target_input_area) { 11435 $('.' + target_input_area).show(); 11436 $(elem).remove(); 11437 return false;
11438} 11439function start_message_sortable() { 11440 $(".drag-link ul").sortable({ 11441 connectWith: ".drag-link ul", 11442 zIndex: 9999, 11443 update: function (event, ui) { 11444 var $elem = ui.item; 11445 var parent = $elem.closest('ul'); 11446 parent.find('.select2-search-field').appendTo(parent); 11447 }, 11448 start: function (event, ui) { 11449 var input = ui.item.closest('p').find('> input'); 11450 var id = ui.item.data().select2Data.id; 11451 input.val(input.val().replace((',' + id), '').replace(id, '')); 11452 input.val().charAt(0) == "," && input.val(input.val().substring(1)); 11453 ui.item.closest('ul').addClass('allow-overflow'); 11454 }, 11455 stop: function (event, ui) { 11456 var $elem = ui.item; 11457 var parent = $elem.closest('ul'); 11458 var id = $elem.data().select2Data.id; 11459 var input = parent.closest('p').find('> input'); 11460 input.val((input.val() == "" ? id : (input.val() + ',' + id))); 11461 $(".drag-link ul").removeClass('allow-overflow'); 11462 } 11463 }).disableSelection(); 11464} 11465function add_sender_placeholder(select2_data, select2_data_size, input_id){ 11466 if (select2_data.length <= 5) { 11467 return false; 11468 } 11469 11470 var input = $(input_id); 11471 var placeholder = $('<div class="senders-placeholder active"><span class="more">more</span></div>').insertBefore( input ); 11472 var more_users = select2_data_size; 11473 var width_alotted = placeholder.width() - 200; 11474 var width_accumulated = 0; 11475 for (i=0; i < select2_data.length; i++) { 11476 var temp = $('<span>' + select2_data[i].text + '</span>').insertBefore(placeholder.find('.more')); 11477 width_accumulated += temp.width(); 11478 if (width_accumulated > width_alotted && placeholder.find('> *').length > 2) { 11479 temp.remove(); 11480 break; 11481 } 11482 more_users -= 1; 11483 } 11484 placeholder.find('.more').text(more_users + ' more'); 11485 placeholder.on('click', function(e){ 11486 if (select2_data.length == select2_data_size) { 11487 e.preventDefault(); 11488 e.stopPropagation(); 11489 placeholder.closest('form').one('click', function(e){ 11490 add_sender_placeholder(select2_data, select2_data_size, input_id); 11491 e.preventDefault(); 11492 e.stopPropagation(); 11493 }); 11494 placeholder.remove(); 11495 } else { 11496 $.alert({content: "You can edit this field only if selected users are upto 50."}); 11497 } 11498 }); 11499 if (more_users == 0) { 11500 placeholder.remove(); 11501 } 11502} 11503 11504/* widgets */ 11505 11506function widget_show_hide(el) { 11507 $.post($(el).attr('href'), function(response) { 11508 location.reload(); 11509 }); 11510} 11511 11512function confirmation_first(el, message) { 11513 $.confirm({ 11514 content: message, 11515 confirm: function(){ 11516 window.location.href = $(el).attr('href'); 11517 } 11518 }); 11519} 11520 11521/* Wallet: toggle show/hide coupon code */ 11522 11523function set_hide_details(user_id, wallet_entry_id, checkbox) { 11524 ajax_request('/wallet/set_hide_details/' + user_id + '?wallet_entry_id=' + wallet_entry_id + '&value=' + (checkbox.checked ? 'true' : 'false')); 11525} 11526 11527/* show message popup */ 11528 11529function toogle_extra_users_list(id1, id2) { 11530 $('#' + id1).hide(); 11531 $('#' + id2).show(); 11532} 11533 11534/* select2 aria */ 11535 11536// Copy aria-label from the underlying control onto select2's auto-generated 11537// search input so screen-reader users hear a meaningful label when focusing 11538// the widget instead of an unnamed text field. 11539function propagate_select2_aria_label(id) { 11540 const $el = $(id); 11541 const label = $el.attr('aria-label'); 11542 if (!label) return; 11543 const $container = $el.select2('container'); 11544 if ($container && $container.length) { 11545 $container.find('input.select2-input').attr('aria-label', label); 11546 } 11547} 11548 11549// Patch Select2 3.4.5 (which generates no ARIA) with the combobox/listbox 11550// design pattern required by WCAG 2.1 SC 4.1.2. 11551function patch_select2_aria(id, isAjax) { 11552 const $el = $(id); 11553 const s2 = $el.data('select2'); 11554 if (!s2) return; 11555 const $container = s2.container; 11556 if (!$container || !$container.length) return; 11557 11558 const $input = $container.find('input.select2-input'); 11559 const listboxId = id.replace(/[^a-zA-Z0-9]/g, '_').replace(/^_+/, '') + '_listbox'; 11560 const isMultiple = s2.opts.multiple || $el.prop('multiple'); 11561 11562 // In single-select mode the search input lives inside the hidden dropdown, so 11563 // attaching combobox ARIA to it produces a broken partial implementation. 11564 // Only multi-select widgets have the input visible in the container. 11565 if (!isMultiple) return; 11566 11567 const ns = '.s2aria_' + listboxId; 11568 11569 $input.attr({ 11570 'role': 'combobox', 11571 'aria-expanded': 'false', 11572 'aria-autocomplete': 'list', 11573 'aria-controls': listboxId 11574 }); 11575 11576 // Set listbox id and role at init time so aria-controls is not dangling before first open. 11577 // The <ul class="select2-results"> exists inside s2.dropdown from Select2 init. 11578 const $initResults = s2.dropdown.find('.select2-results'); 11579 if ($initResults.length) { 11580 // Select2 only detaches the dropdown from <body> in destroy(), which nothing calls, so a 11581 // popup that is closed and reopened leaves an orphaned listbox still holding this id. 11582 // Release it before claiming it or aria-controls resolves to that stale, emptied node. 11583 $('[id="' + listboxId + '"]').not($initResults).removeAttr('id'); 11584 const initAttrs = {'id': listboxId, 'role': 'listbox'}; 11585 if (isMultiple) { initAttrs['aria-multiselectable'] = 'true'; } 11586 $initResults.attr(initAttrs); 11587 } 11588 11589 function patchResults() { 11590 // Bail if this instance is not currently open — prevents clobbering another widget's 11591 // listbox when a late AJAX response fires while a different filter's dropdown is open. 11592 if (!s2.opened()) return; 11593 const $results = s2.dropdown.find('.select2-results'); 11594 if (!$results.length) return; 11595 const listboxAttrs = {'role': 'listbox', 'id': listboxId}; 11596 if (isMultiple) { listboxAttrs['aria-multiselectable'] = 'true'; } 11597 $results.attr(listboxAttrs); 11598 let selectedVals = $el.select2('val') || []; 11599 if (!Array.isArray(selectedVals)) { selectedVals = selectedVals ? [selectedVals] : []; } 11600 $results.find('li.select2-result-selectable').each(function(i) { 11601 const optionData = $(this).data('select2-data'); 11602 const isSelected = optionData && selectedVals.indexOf(String(optionData.id)) !== -1; 11603 const attrs = {'role': 'option', 'aria-selected': isSelected ? 'true' : 'false', 'id': listboxId + '_' + i}; 11604 if (isAjax) { attrs['aria-setsize'] = '-1'; attrs['aria-posinset'] = i + 1; } 11605 $(this).attr(attrs); 11606 }); 11607 // Status items injected into the same <ul> — give them role="option" aria-disabled="true" 11608 // so the listbox has no invalid children. Includes select2-selection-limit (rendered at 11609 // select2.js:1600 when maximumSelectionSize is reached). 11610 $results.children('li.select2-searching, li.select2-no-results, li.select2-more-results, li.select2-selection-limit') 11611 .attr({'role': 'option', 'aria-disabled': 'true'}); 11612 // Sync aria-activedescendant now that all options have ids — select2-highlight fires 11613 // before patchResults() on first open, so the initial highlight would otherwise be missed. 11614 const $highlighted = $results.find('.select2-highlighted'); 11615 const highlightedId = $highlighted.attr('id'); 11616 if (highlightedId) { 11617 $input.attr('aria-activedescendant', highlightedId); 11618 } else { 11619 $input.removeAttr('aria-activedescendant'); 11620 } 11621 } 11622 11623 // Override the instance's opening() method so patchResults() runs
11623inside Select2's own 11624 // call chain, after AbstractSelect2.opening() has moved the dropdown to <body> and set 11625 // id="select2-drop", and after updateResults(true) has populated results for static data. 11626 const originalOpening = s2.opening; 11627 s2.opening = function() { 11628 originalOpening.apply(this, arguments); 11629 $input.attr('aria-expanded', 'true'); 11630 patchResults(); 11631 }; 11632 11633 // Wrap opts.query so patchResults() runs after every results render, including the 11634 // "No matches found" path. select2-loaded is not triggered when results.length === 0 11635 // (select2.js:1675-1678 returns early), and the keyup handler holds a direct reference 11636 // to the original updateResults so overriding s2.updateResults misses keypress events. 11637 const originalQuery = s2.opts.query; 11638 s2.opts.query = function(options) { 11639 const originalCallback = options.callback; 11640 options.callback = function(data) { 11641 originalCallback(data); 11642 patchResults(); 11643 }; 11644 originalQuery.call(this, options); 11645 }; 11646 11647 // Tear down any listeners from a prior patch_select2_aria call on this element before 11648 // rebinding — prevents handler stacking when the same element is re-initialised 11649 // (e.g. init_filterable_select called twice on a fixed id like 'tags_selector'). 11650 $el.off(ns); 11651 $input.off(ns); 11652 11653 // For AJAX filters: results arrive after the initial open (select2-loaded fires after 11654 // each AJAX response), so we also patch via the event to catch those updates. 11655 $el.on('select2-loaded' + ns, function() { 11656 patchResults(); 11657 }); 11658 11659 // Re-patch after every selection change so aria-selected stays in sync. 11660 // MultiSelect2.onSelect triggers 'selected' (not 'select2-selected') — bind both. 11661 $el.on('select2-selected' + ns + ' selected' + ns + ' select2-removed' + ns, function() { 11662 patchResults(); 11663 }); 11664 11665 // Label each chip's remove button so screen readers can announce what is selected. 11666 // Selected items are hidden by Select2 CSS and never appear in the listbox, 11667 // so aria-selected on options cannot expose selection state — the chips must. 11668 // Use MutationObserver so chips are patched immediately on DOM insertion, 11669 // independent of which Select2 event fires (differs between static and AJAX filters). 11670 const removeLabel = $el.attr('data-remove-label') || ''; 11671 function patchChip($chip) { 11672 const text = $chip.find('div').first().text(); 11673 if (text) { $chip.find('.select2-search-choice-close').attr('aria-label', removeLabel ? removeLabel + ' ' + text : text); } 11674 } 11675 const $choices = $container.find('.select2-choices'); 11676 if ($choices.length) { 11677 new MutationObserver(function(mutations) { 11678 mutations.forEach(function(m) { 11679 $(m.addedNodes).filter('.select2-search-choice').each(function() { patchChip($(this)); }); 11680 }); 11681 }).observe($choices[0], { childList: true }); 11682 } 11683 // Patch any pre-selected chips that exist at init time. 11684 $container.find('.select2-search-choice').each(function() { patchChip($(this)); }); 11685 11686 $el.on('select2-close' + ns, function() { 11687 $input.attr('aria-expanded', 'false'); 11688 $input.removeAttr('aria-activedescendant'); 11689 }); 11690 11691 $el.on('select2-highlight' + ns, function() { 11692 if (!s2.opened()) return; 11693 const $highlighted = s2.dropdown.find('.select2-highlighted'); 11694 const highlightedId = $highlighted.attr('id'); 11695 if (highlightedId) $input.attr('aria-activedescendant', highlightedId); 11696 }); 11697 11698 // Patch status <li>s rendered by updateResults early-return paths (formatInputTooShort, 11699 // formatInputTooLong, selection limit) which call results.html() then return before 11700 // opts.query is ever invoked. Defer 0 ms so select2's synchronous render completes first. 11701 $input.on('keyup-change' + ns + ' input' + ns + ' paste' + ns, function() { 11702 setTimeout(patchResults, 0); 11703 }); 11704} 11705 11706/* categories, tags select2 */ 11707 11708function init_filterable_select(id, inputs, suggest_url) { 11709 $('input#' + id).select2({ 11710 multiple : true, 11711 allowClear: true, 11712 maximumSelectionSize : 40, // for limitation of people number in the "to" fields 11713 minimumInputLength : 2, // minimum chars to start the suggest query 11714 initSelection : function (element, callback) { 11715 var data = []; 11716 $.each(inputs, function (i, v) { 11717 data.push({id: v, text: v}); 11718 }); 11719 callback(data); 11720 }, 11721 ajax : { 11722 type : "GET", 11723 url : suggest_url, 11724 dataType : 'json', 11725 quietMillis : 500, // bigger delay before ajax is called 11726 data : function(term) { 11727 return { 11728 q : term 11729 }; 11730 }, 11731 results : function(data) { 11732 var results = { 11733 results : [] 11734 }; 11735 11736 $.each(data, function() { 11737 results.results.push({ 11738 id : this.id, 11739 text : this.value 11740 }); 11741 }); 11742 11743 return results; 11744 } 11745 } 11746 });
11747 propagate_select2_aria_label('input#' + id); 11748 patch_select2_aria('input#' + id, true); 11749} 11750 11751/* tags select2 */ 11752 11753function init_subjects_select(id, subjects, suggest_url) { 11754 $('input#' + id).select2({ 11755 multiple : true, 11756 allowClear: true, 11757 maximumSelectionSize : 40, // for limitation of people number in the "to" fields 11758 minimumInputLength : 2, // minimum chars to start the suggest query 11759 initSelection : function (element, callback) { 11760 var data = []; 11761 $.each(subjects, function (i, v) { 11762 data.push({id: v[0], value: v[0], text: v[1]}); 11763 }); 11764 callback(data); 11765 }, 11766 ajax : { 11767 type : "GET", 11768 url : suggest_url, 11769 dataType : 'json', 11770 quietMillis : 500, // bigger delay before ajax is called 11771 data : function(term) { 11772 return { 11773 subject : term 11774 }; 11775 }, 11776 results : function(data) { 11777 var results = { 11778 results : [] 11779 }; 11780 11781 $.each(data, function() { 11782 results.results.push({ 11783 id : this.id, 11784 value: this.value, 11785 text : this.label 11786 }); 11787 }); 11788 11789 return results; 11790 } 11791 } 11792 }); 11793 propagate_select2_aria_label('input#' + id); 11794 patch_select2_aria('input#' + id, true); 11795} 11796 11797function quotas_select() { 11798 $('#users').select2({ 11799 multiple: true, 11800 maximumSelectionSize : 40, // for limitation of people number in the "to" fields 11801 minimumInputLength : 2, // minimum chars to start the suggest query
11802 ajax: { 11803 type : "GET", 11804 url: '/copilot_admin/suggest_users', 11805 dataType: 'json', 11806 quietMillis: 300, 11807 data: function (term) { 11808 q = term; 11809 return { 11810 name : q 11811 }; 11812 }, 11813 results: function (data) { 11814 results = { 11815 results : [] 11816 }; 11817 preload_data = data.results; 11818 11819 $.each(preload_data, function() { 11820 ln = this.last_name; 11821 fn = this.first_name; 11822 tln = ln.toUpperCase(); 11823 tfn = fn.toUpperCase(); 11824 tfnln = tfn + ' ' + tln; 11825 tlnfn = tln + ' ' + tfn; 11826 11827 q = q.trim(); 11828 q = q.toUpperCase(); 11829 11830 if (tln.indexOf(q) >= 0 || tfn.indexOf(q) >= 0 || tfnln.indexOf(q) >= 0 || tlnfn.indexOf(q) >= 0) { 11831 results.results.push({ 11832 id : this.id, 11833 text : fn + ' ' + ln 11834 }); 11835 } 11836 }); 11837 11838 // the #users input will contain the ids: id1,id2,id3 11839 return results; 11840 } 11841 } 11842 }); 11843} 11844 11845/* parse and create a variable object */ 11846function getUrlVars(from) { 11847 var vars = {}, hash; 11848 var hashes = from.slice(from.indexOf('?') + 1).split('&'); 11849 11850 for(var i = 0; i < hashes.length; i++) 11851 { 11852 hash = hashes[i].split('='); 11853 vars[hash[0]] = hash[1]; 11854 } 11855 11856 return vars; 11857} 11858 11859// check file processing job status 11860 11861var only_one_file_check = true; 11862 11863function check_document_processing_status(id) { 11864 if (only_one_file_check == false) { 11865 return false; 11866 } 11867 11868 only_one_file_check = false; 11869 11870 setInterval(function() { 11871 $.get('/file_processing/check_status/' + id, function(response) { 11872 if (response.status == 'reload') { 11873 location.reload(); 11874 } 11875 }); 11876 }, 3000); 11877} 11878 11879// kaltura 11880 11881function kaltura_resource_create(url, title) { 11882 var parent_form = window.parent.$("form#kaltura_uploader_form"); 11883 11884 parent_form.append('<input type="hidden" name="attachment_url" id="attachment_url" value="' + url + '">'); 11885 parent_form.append('<input type="hidden" name="attachment_name" id="attachment_name" value="' + title + '">'); 11886 11887 parent_form.submit(); 11888} 11889 11890function kaltura_attachment_create(url, title) { 11891 var parent_wrapper = window.parent.$("div#kaltura_uploader_form"); 11892 var main_wrapper = parent_wrapper.find("#kaltura_wrapper").val(); 11893 var objects = {}; 11894 11895 if ((main_wrapper == "post_filecontainer") || (main_wrapper == "announcement_filecontainer")) { 11896 objects[title] = url; 11897 window.parent.append_multiple_files(objects); 11898 window.parent.$.facebox.close(); 11899 } 11900} 11901 11902/* change message fields */ 11903 11904function toggleMessageFields(el) { 11905 changeLinksText(el); 11906 changeInputsLabelAndId(el); 11907} 11908 11909var inputMap = { 11910 'to': ['Cc', 'Bcc'], 11911 'cc': ['To', 'Bcc'], 11912 'bcc': ['To', 'Cc'] 11913}; 11914 11915function changeLinksText(el){ 11916 $('#cc_link').text(inputMap[el.value][0]); 11917 $('#bcc_link').text(inputMap[el.value][1]); 11918} 11919 11920function changeInputsLabelAndId(el){ 11921 $('.cc_label').text(inputMap[el.value][0] + ':'); 11922 $('.bcc_label').text(inputMap[el.value][1] + ':'); 11923 changeFieldsSequence(el.value); 11924} 11925 11926function changeFieldsSequence(element){ 11927 for (var i = 0; i <= 2; i++) { 11928 $('.message-fields.select2-offscreen')[i]['id'] = fieldsList(element)[i]; 11929 } 11930} 11931 11932function fieldsList(element) { 11933 var inputMap = { 11934 'to': ['to', 'cc', 'bcc'], 11935 'cc': ['cc', 'to', 'bcc'], 11936 'bcc': ['bcc', 'to', 'cc'] 11937 }; 11938 return inputMap[element] 11939} 11940 11941// app center search 11942 11943function app_center_search() { 11944 var storage = []; 11945 11946 $('.catalog_boxes > div').each(function(i) { 11947 $(this).data('initial-index', i); 11948 }); 11949 11950 $("#app_center_search").on("keyup", function() { 11951 var value = $(this).val().toLowerCase(); 11952 var to_remove = []; 11953 11954 $(".catalog_boxes > div").filter(function() { 11955 if ($(this).text().toLowerCase().indexOf(value) < 0) { 11956 storage.push($(this)); 11957 $(this).detach(); 11958 } 11959 }); 11960 11961 $.each(storage, function(i, v) { 11962 if ($(v).text().toLowerCase().indexOf(value) > -1) { 11963 to_remove.push(i); 11964 $('.catalog_boxes').append(v); 11965 } 11966 }); 11967 11968 $.each(to_remove, function(i,v) { 11969 storage.splice(v, 1); 11970 }); 11971 11972 $('.catalog_boxes > div').sort(function(a, b) { 11973 return $(a).data('initial-index') - $(b).data('initial-index'); 11974 }).appendTo('.catalog_boxes'); 11975 }); 11976} 11977 11978function app_center_search_new() { 11979 var phrase, categories; 11980 11981 $('#filter_form #phrase').keyup(function(e) { 11982 typewatch(function() { 11983 redirect(); 11984 }, 1000); 11985 }); 11986 11987 $('.users_filter').on('change', function(e) { 11988 redirect(); 11989 }); 11990 11991 var redirect = function() { 11992 let path = window.location.href.split('?')[0] 11993 let query = []; 11994 11995 phrase = $('#filter_form #phrase').val().trim(); 11996 11997 if (phrase != '') { 11998 query.push('phrase=' + phrase); 11999 } 12000 12001 categories = $('#filter_form .users_filter:checked'); 12002 12003 $.each(categories, function(i,v) { 12004 query.push($(v).attr('name') + '=true'); 12005 }); 12006 12007 window.location.href = path + (query.length > 0 ? '?' + query.join('&') : ''); 12008 } 12009} 12010 12011// Google Fonts 12012 12013var google_fonts_data; 12014var google_fonts_data_initial; 12015var google_fonts_offset = 0; 12016var google_fonts_limit = 50; 12017var google_fonts_loading; 12018var google_fonts_scroll_pause = false;
12019var google_fonts_scroll_stop = false; 12020var google_fonts_selected = []; 12021 12022function get_google_fonts() { 12023 google_fonts_offset = 0; 12024 google_fonts_limit = 50; 12025 google_fonts_scroll_pause = false; 12026 google_fonts_scroll_stop = false; 12027 12028 $.each(google_fonts_selected, function(i, v) { 12029 $('#google_fonts_form').append('<input type="hidden" name="google_font[]" value="' + v + '" >'); 12030 }); 12031 12032 $('.google_fonts_top input').on("keyup", delay(function() { 12033 var term = $(this).val(); 12034 12035 if (term.length > 1) { 12036 google_fonts_data = google_font_search(term); 12037 } else { 12038 google_fonts_data = google_fonts_data_initial; 12039 } 12040 12041 google_fonts_scroll_pause = false; 12042 google_fonts_scroll_stop = false; 12043 google_fonts_offset = 0; 12044 list_google_fonts(); 12045 })); 12046 12047 function delay(fn) { 12048 var timer = 0; 12049 return function() { 12050 $('.fonts_holder').html(google_fonts_loading); 12051 clearTimeout(timer); 12052 timer = setTimeout(fn.bind(this, arguments), 700 || 0); 12053 } 12054 } 12055 12056 $.get('/google_fonts/list', function(json) { 12057 google_fonts_data = json.items; 12058 google_fonts_data_initial = json.items; 12059 google_fonts_loading = $('.fonts_holder').find('.fonts_loading'); 12060 12061 list_google_fonts(); 12062 12063 $("#facebox .facebox-content, .modal.is-open .facebox-content").scroll(function() { 12064 if (!google_fonts_scroll_pause) { 12065 if ($(this).scrollTop() >= ($(this)[0].scrollHeight - $(this).height() - 50)) { 12066 12067 google_fonts_scroll_pause = true; 12068 12069 if (!google_fonts_scroll_stop) { 12070 list_google_fonts(); 12071 } 12072 } 12073 } 12074 }); 12075 }); 12076} 12077 12078function list_google_fonts() { 12079 var fonts = []; 12080 var embed_link = "https://fonts.googleapis.com/css2?"; 12081 12082 if (google_fonts_data.length == 0) { 12083 $('.fonts_holder').find('.fonts_loading').remove(); 12084 $('.fonts_holder').append("<li><span class='no-results'>No fonts found</span></li>"); 12085 return false; 12086 } 12087 12088 if (google_fonts_offset < google_fonts_data.length) { 12089 for (var i = google_fonts_offset; i < (google_fonts_offset + google_fonts_limit); i++) { 12090 if (google_fonts_data[i]) { 12091 google_fonts_data[i].index = i; 12092 12093 fonts.push(google_fonts_data[i]); 12094 12095 if (i == google_fonts_offset) { 12096 embed_link = embed_link + "family=" + google_fonts_data[i].family; 12097 } else { 12098 embed_link = embed_link + "&family=" + google_fonts_data[i].family; 12099 } 12100 } 12101 } 12102 12103 $('.fonts_holder').append("<link href=\"" + embed_link + "\" rel=\"stylesheet\">"); 12104 12105 setTimeout(function() { 12106 $('.fonts_holder').find('.fonts_loading').remove(); 12107 12108 $.each(fonts, function(i,font) { 12109 $('.fonts_holder').append("<li>" + 12110 "<input id=\"google_font_" + font.index + "\" name=\"google_font_" + font.index + "\" type=\"checkbox\" value=\"" + font.family + "\"" + ((google_fonts_selected && (google_fonts_selected.indexOf(font.family) !== -1)) ? ' checked' : '') + " onchange=\"check_google_font(this)\">" + 12111 "<label for=\"google_font_" + font.index + "\"><span>Font family: <b>" + font.family + "</b>, category: <b>" + font.category + "</b></span><span style=\"font-family: '" + font.family + "', " + font.category + ";\">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In pellentesque orci ex, eget pellentesque ex efficitur eu.</label>" + 12112 "</li>"); 12113 }); 12114 12115 google_fonts_offset = google_fonts_offset + fonts.length; 12116 google_fonts_scroll_pause = false; 12117 12118 if (google_fonts_offset < google_fonts_data.length) { 12119 $('.fonts_holder').append(google_fonts_loading); 12120 } 12121 }, 1000); 12122 } 12123 12124 if (google_fonts_offset >= google_fonts_data.length) { 12125 google_fonts_scroll_stop = true; 12126 $('.fonts_holder').find('.fonts_loading').remove(); 12127 } 12128} 12129 12130function check_google_font(el) { 12131 var $this = $(el); 12132 12133 if ($this.is(':checked')) { 12134 google_fonts_selected.push($this.val()); 12135 $('#google_fonts_form').append('<input type="hidden" name="google_font[]" value="' + $this.val() + '" >'); 12136 } else { 12137 var index = google_fonts_selected.indexOf($this.val()); 12138 12139 if (index > -1) { 12140 google_fonts_selected.splice(index, 1); 12141 $('#google_fonts_form input:hidden').filter(function(){return this.value == $this.val()}).remove(); 12142 } 12143 } 12144} 12145 12146function google_font_search(term) { 12147 return $.grep(google_fonts_data_initial, function(font, index) {
12148 return (font.family.toLowerCase().indexOf(term.toLowerCase()) !== -1); 12149 }); 12150} 12151 12152// MS Immersive Reader 12153 12154function launchImmersiveReaderFromInlineHtml($this, contentLanguage) { 12155 const elements = $('[data-immersive-reader="true"]'); 12156 let content = ''; 12157 12158 if (elements.length > 0) { 12159 let contentArray = []; 12160 let clonedElements = elements.clone(); 12161 12162 clonedElements.each(function() { 12163 var $element = $(this); 12164 12165 // Remove all script tags 12166 $element.find('script').remove(); 12167 12168 // Replace audio player with text 12169 $element.find('.resource-flowplayer-audio').each(function() { 12170 $(this).replaceWith('<p>[Audio file available]</p>'); 12171 }); 12172 12173 // Replace video player with text 12174 $element.find('.resource-flowplayer-video').each(function() { 12175 $(this).replaceWith('<p>[Video file available]</p>'); 12176 }); 12177 12178 contentArray.push($element.html()); 12179 }); 12180 12181 content = contentArray.join('\n\n'); 12182 } else { 12183 const buttonHolder = $($this).parent('.immersive-reader-button-holder'); 12184 12185 let element = buttonHolder.nextAll('.materialStyle').first(); 12186 12187 if (element.length == 0) { 12188 element = buttonHolder.nextAll('.widget-view-mode') 12189 .children('.materialStyle') 12190 .first(); 12191 } 12192 12193 if (element.length == 0) { 12194 element = buttonHolder.nextAll('.micro-card-container') 12195 .children('.micro-card') 12196 .children('.materialStyle') 12197 .first(); 12198 } 12199 12200 if (element.length == 1) { 12201 content = element.html(); 12202 } else { 12203 return false; 12204 } 12205 } 12206 12207 const data = { 12208 chunks: [{ 12209 mimeType: 'text/html', 12210 content: content, 12211 lang: contentLanguage 12212 }] 12213 }; 12214 12215 $.get('/immersive_reader_token/fetch', function(response) { 12216 if (response.status == 'ok') { 12217 ImmersiveReader.launchAsync(response.token, response.subdomain, data); 12218 } else { 12219 $.alert({content: response.message}) 12220 } 12221 }); 12222} 12223 12224// Update unarchive user count 12225 12226function edit_unarchive_user_percentage() { 12227 element = $('#reactivate_user_percentage'); 12228 element.prop("disabled", false); 12229 element.data('original_value', element.val()); 12230 toggle_unarchive_buttons(); 12231} 12232 12233function save_unarchive_user_percentage(school_id) { 12234 element = $('#reactivate_user_percentage'); 12235 $.post('/school/update_archived_user_percentage/' + school_id, { value: element.val() }); 12236 element.data('original_value', element.val()); 12237 toggle_unarchive_buttons(); 12238 element.prop("disabled", true); 12239} 12240 12241function cancel_unarchive_user_percentage() { 12242 element = $('#reactivate_user_percentage'); 12243 element.val(element.data('original_value')); 12244 toggle_unarchive_buttons(); 12245 element.prop("disabled", true); 12246} 12247 12248function toggle_unarchive_buttons() { 12249 $('#save_unarchive').toggle(); 12250 $('#cancel_unarchive').toggle(); 12251 $('#edit_unarchive').toggle(); 12252} 12253 12254// Peer reviews 12255 12256function dismiss_assigning_error(el, controller, id, student_id) { 12257 $.post('/' + controller + '/dismiss_error/' + id, {student: student_id}, function(response) { 12258 var parent = $(el).parent('p'); 12259 12260 parent.fadeOut(500, function() { 12261 parent.remove(); 12262 }); 12263 }); 12264} 12265 12266function scroll_to_top(offset) { 12267 $('html, body').animate({ 12268 scrollTop: offset 12269 }, 50); 12270} 12271 12272function set_require_safe_exam_browser_for_assignment(id, checkbox) { 12273 $.post('/teacher_assignment/set_requires_safe_exam_browser/' + id, {value: check_s(checkbox)}); 12274 var additional_options = $('#seb_enabled_options'); 12275 12276 if (checkbox.checked) { 12277 additional_options.show(); 12278 $('.access_code_section').hide(); 12279 } else { 12280 additional_options.hide(); 12281 $('.access_code_section').show(); 12282 } 12283} 12284 12285// SCORM preview image upload progress 12286 12287function preview_image_upload_progress(id) { 12288 const file_input = document.getElementById(id); 12289 const reader = new FileReader(); 12290 const progress_bar = $('#' + id + '_progress'); 12291 12292 file_input.addEventListener('change', function (){ 12293 const selected_file = file_input.files[0]; 12294 12295 if (selected_file) { 12296 reader.addEventListener('loadstart', function (e) { 12297 progress_bar.css({ 12298 'background': "#fff", 12299 'border': '1px solid #ccc', 12300 'width': '278px', 12301 'height': '20px', 12302 'text-align': 'right', 12303 'font-weight': 'bold' 12304 }); 12305 12306 progress_bar.html('0%'); 12307 progress_bar.show(); 12308 }); 12309 12310 reader.addEventListener('load', function (e) { 12311 progress_bar.html('100%'); 12312 progress_bar.css('background', '#85C3CC'); 12313 }); 12314 12315 reader.addEventListener('progress', function (e) { 12316 if (e.lengthComputable) { 12317 const percentLoaded = Math.round((e.loaded / e.total) * 100); 12318 12319 if (percentLoaded < 100) { 12320 progress_bar.html(percentLoaded + '%'); 12321 progress_bar.css('background', 'linear-gradient(90deg, #85C3CC ' + percentLoaded + '%, #fff ' + percentLoaded + '%)'); 12322 } 12323 } 12324 }); 12325
12326 reader.readAsDataURL(selected_file); 12327 } 12328 }); 12329} 12330 12331// 12332 12333function generate_alexa_key() { 12334 $.get('/account/generate_alexa_login_key', function(data) { 12335 if (data.key) { 12336 $('span.alexa-key-holder').html(data.key); 12337 } else { 12338 $.alert({content: "There was an error generating the login key. Please try again."}); 12339 } 12340 }); 12341} 12342 12343// SCORM launch with preview image 12344 12345function launch_scorm_iframe(id, url) { 12346 var iframe = $("#" + id); 12347 iframe.parent().show(); 12348 iframe.attr('src', url); 12349 $("#" + id + "_play_button").hide(); 12350} 12351 12352function mobile_cache_page( crc, url ){ 12353 if(window.webkit) 12354 webkit.messageHandlers.cordova_iab.postMessage(JSON.stringify({'data': {'crc': crc, 'url': url}, 'method': 'app.AcceleratorAPI.loadPage'})); 12355 else 12356 setTimeout(function(){ 12357 //get a better solution later timing is off 12358 webkit.messageHandlers.cordova_iab.postMessage(JSON.stringify({'data': {'crc': crc, 'url': url}, 'method': 'app.AcceleratorAPI.loadPage'})); 12359 },200); 12360 12361} 12362 12363// scheduled posts 12364 12365function delete_scheduled_post(url, posting_id) { 12366 $.confirm({ 12367 content: 'Are you sure you want to delete it?', 12368 confirm: function () { 12369 ajax_request(url); 12370 12371 $.when($('#scheduled_post_' + posting_id).fadeOut()).done(function () { 12372 update_min_height(); 12373 $('#scheduled_post_' + posting_id).remove(); 12374 12375 if ($('.scheduled_posting_row').length === 0) { 12376 $('#scheduled_post_option_btn').hide(); 12377 $.facebox.close(); 12378 } 12379 }); 12380 } 12381 }); 12382} 12383 12384// switch between mobile and desktop filter mode 12385 12386function check_new_filter(mobile_holder_selector = "div.mobile_only div.categories_holder", desktop_holder_selector = "div.desktop_only.categories_holder") { 12387 var window_width = (window.innerWidth > 0) ? window.innerWidth : screen.width; 12388 12389 if ((window_width > 979) && ($(mobile_holder_selector + " form#filter_form").length > 0)) { 12390 // move form from div.mobile_only to div.desktop_only 12391 $(desktop_holder_selector).append($(mobile_holder_selector + "form#filter_form")); 12392 $(desktop_holder_selector + " form#filter_form").show(); 12393 }else if ((window_width <= 979) && ($(desktop_holder_selector + " form#filter_form").length > 0)) { 12394 // move form from div.desktop_only to div.mobile_only 12395 $(mobile_holder_selector).append($(desktop_holder_selector + " form#filter_form")); 12396 if ($('a[data-element="filter_form"]').attr('aria-expanded') === 'true') { 12397 $(mobile_holder_selector + " form#filter_form").show(); 12398 }else { 12399 $(mobile_holder_selector + " form#filter_form").hide(); 12400 } 12401 } 12402} 12403 12404// check cookies status 12405 12406function check_cookies_status() { 12407 $.getJSON("/info/check_cookies_status", function (data) { 12408 if (data.cookies_disabled) { 12409 window.location.href = "/info/no_cookies"; 12410 } 12411 }); 12412} 12413 12414// group catalog filter 12415 12416function update_groups_filter(url) { 12417 var checkboxes = $('input[type=checkbox].groups_filter'); 12418 var dropdowns = $('select.groups_filter'); 12419 var name = $('input#name_filter'); 12420 12421 for (var i = 0; i < checkboxes.length; i += 1) { 12422 var checkbox = checkboxes[i]; 12423 12424 if (checkbox.checked) { 12425 url += '&' + checkbox.name + '=true'; 12426 } 12427 } 12428 12429 for (var i = 0; i < dropdowns.length; i += 1) { 12430 var dropdown = dropdowns[i]; 12431 url += '&' + dropdown.name + '=' + dropdown.value; 12432 } 12433 12434 if (name.val() != '') { 12435 url += '&name_filter=' + encodeURIComponent(name.val()); 12436 } 12437 12438 let focusedId = document.activeElement && document.activeElement.id; 12439 $(window).one('loadcomplete', function() { 12440 if (focusedId) { 12441 let el = document.getElementById(focusedId); 12442 if (el && typeof el.focus === 'function') el.focus(); 12443 } 12444 }); 12445 Excalibur.Router.load( url, '#mainContent' ); 12446} 12447 12448function init_group_name_filter(url, query) { 12449 $(document).on("keydown", "#filter_form", function(event) { 12450 return event.key != "Enter"; 12451 }); 12452 12453 var input = $('input#name_filter'); 12454 12455 input.keyup(function(e) { 12456 typewatch(function() { 12457 var value = input.val().trim(); 12458 12459 if (value != query) { 12460 update_groups_filter(url); 12461 } 12462 }, 1000); 12463 }); 12464} 12465 12466// class catalog: switch between mobile and desktop filter mode 12467 12468function check_class_catalog_filter() { 12469 var window_width = (window.innerWidth > 0) ? window.innerWidth : screen.width; 12470 12471 if ((window_width > 979) && ($("#class_mobile_filter_holder form#filter_form").length > 0)) { 12472 $("#class_desktop_filter_holder").append($("#class_mobile_filter_holder form#filter_form")); 12473 $("#class_desktop_filter_holder form#filter_form").show(); 12474 }else if ((window_width <= 979) && ($("#class_desktop_filter_holder form#filter_form").length > 0)) { 12475 $("#class_mobile_filter_holder").append($("#class_desktop_filter_holder form#filter_form")); 12476 if ($('a[data-element="filter_form"]').attr('aria-expanded') === 'true') { 12477 $("#class_mobile_filter_holder form#filter_form").show(); 12478 }else { 12479 $("#class_mobile_filter_holder form#filter_form").hide(); 12480 } 12481 } 12482} 12483 12484// course catalog filter 12485 12486function update_course_catalog_filter(url) { 12487 if ($('#is_calendar_mode').val() == 'true') { 12488 update_calendar(window.current_year, window.current_month, window.current_day); 12489 return; 12490 } 12491 12492 Excalibur.Location_tools.add_load_indicator($('#class_catalog_container'), 100); 12493 $('.clear_filter').show(); 12494 12495 $.get(url + generate_course_filter_params(), function(data){ 12496 setTimeout(function(){ $('#class_catalog_container').removeClass('extended-load').html(data); }, 200); 12497 12498 $(window).off('loadcomplete.course_rating').on('loadcomplete.course_rating', function () { 12499 jQuery('.ratingStatic').each(function () { 12500 jQuery(this).addRatingStatic(jQuery(this).data().rating); 12501 }); 12502 }); 12503 }); 12504} 12505 12506function init_course_name_filter(url, query) { 12507 $(document).off('keydown', 'input#name_filter'); 12508 $(document).on("keydown", "#filter_form", function(event) { 12509 return event.key != "Enter"; 12510 }); 12511 12512 var input = $('input#name_filter'); 12513
12514 input.keyup(function(e) { 12515 typewatch(function() { 12516 var value = input.val().trim(); 12517 12518 if (value != '' && value != query) { 12519 query = value; 12520 update_course_catalog_filter(url + '?&phrase=' + encodeURIComponent(value)); 12521 } else if (value == '' && value != query) { 12522 query = value; 12523 update_course_catalog_filter(url); 12524 } 12525 }, 1000); 12526 }); 12527} 12528 12529function generate_course_filter_params() { 12530 var url = ''; 12531 var dropdowns = $('select.course_filter'); 12532 var name = $('input#name_filter'); 12533 12534 for (var i = 0; i < dropdowns.length; i += 1) { 12535 var dropdown = dropdowns[i]; 12536 url += '&' + dropdown.name + '=' + encodeURIComponent(dropdown.value); 12537 } 12538 12539 if (name.val() != '') { 12540 url += '&phrase=' + encodeURIComponent(name.val()); 12541 } 12542 12543 if (window.visitor_mode) { 12544 url += '&visitor_mode=true'; 12545 } 12546 12547 return url; 12548} 12549 12550// users filter 12551 12552function init_users_filter(id, url, query) { 12553 var input = $('input#' + id); 12554 12555 if (id == 'name_filter') { 12556 var extra_params = '&name_changed=true&email_changed=false&'; 12557 }else { 12558 var extra_params = '&name_changed=false&email_changed=true&'; 12559 } 12560 12561 input.keyup(function(e) { 12562 typewatch(function() { 12563 var value = input.val().trim(); 12564 12565 if (value != '' && value != query) { 12566 update_users_filter(url + extra_params + id + '=' + encodeURIComponent(value)); 12567 } else if (value == '' && value != query) { 12568 update_users_filter(url); 12569 } 12570 }, 1000); 12571 }); 12572} 12573 12574function update_users_filter(url) { 12575 var checkboxes = $('input[type=checkbox].users_filter'); 12576 var dropdowns = $('select.users_filter'); 12577 var name = $('input#name_filter'); 12578 var email = $('input#email_filter'); 12579 12580 for (var i = 0; i < checkboxes.length; i += 1) { 12581 var checkbox = checkboxes[i]; 12582 12583 if (checkbox.checked) { 12584 url += '&' + checkbox.name + '=true'; 12585 } 12586 } 12587 12588 for (var i = 0; i < dropdowns.length; i += 1) { 12589 var dropdown = dropdowns[i]; 12590 url += '&' + dropdown.name + '=' + dropdown.value; 12591 } 12592 12593 if (name.val() != '') { 12594 url += '&name_filter=' + encodeURIComponent(name.val()); 12595 } 12596 12597 if (email.val() != '') { 12598 url += '&email_filter=' + encodeURIComponent(email.val()); 12599 } 12600 12601 Excalibur.Router.load( url, '#mainContent' ); 12602} 12603 12604// reports filter 12605 12606function init_reports_name_filter(url, query) { 12607 $(document).on("keydown", "#filter_form", function(event) { 12608 return event.key != "Enter"; 12609 }); 12610 12611 var input = $('input#name_filter'); 12612 12613 input.keyup(function(e) { 12614 typewatch(function() { 12615 var value = input.val().trim(); 12616 12617 if (value != '' && value != query) { 12618 update_reports_catalog_filter(url + '?&phrase=' + encodeURIComponent(value)); 12619 } else if (value == '' && value != query) { 12620 update_reports_catalog_filter(url); 12621 } 12622 }, 1000); 12623 }); 12624} 12625 12626function update_reports_catalog_filter(url) { 12627 var checkboxes = $('input[type=checkbox].report_filter'); 12628 var report_type = $('select#report_type'); 12629 var name = $('input#name_filter'); 12630 12631 for (var i = 0; i < checkboxes.length; i += 1) { 12632 var checkbox = checkboxes[i]; 12633 12634 if (checkbox.checked) { 12635 url += '&' + checkbox.name + '=true'; 12636 } 12637 } 12638 12639 if (report_type.length > 0) { 12640 url += '&report_type=' + report_type.val(); 12641 } 12642 12643 if (name.val() != '') { 12644 url += '&name_filter=' + encodeURIComponent(name.val()); 12645 } 12646 12647 Excalibur.Router.load( url, '#mainContent' ); 12648} 12649 12650function clear_filter() { 12651 var filter_url = $(this).attr("filter-url") 12652 12653 Excalibur.Router.load( filter_url, (window.visitor_mode ? '#contentBody' : '#mainContent') ); 12654} 12655 12656function show_or_hide_saved_items(item_type, item_id) { 12657 var dropdown = $('#saved_' + item_type + 's_' + item_id); 12658 12659 if (!dropdown.data('visible')) { 12660 $('#' + item_type + '_' + item_id + ' ul').show(); 12661 dropdown.data('visible', true); 12662 dropdown.find('i').removeClass('arrowDown').addClass('arrowUp'); 12663 }else { 12664 $('#' + item_type + '_' + item_id + ' ul').hide(); 12665 dropdown.data('visible', false); 12666 dropdown.find('i').removeClass('arrowUp').addClass('arrowDown'); 12667 } 12668} 12669 12670// list widget ajax - list_widget_content('.classes_widget', 'get_classes_list'); 12671 12672function list_widget_content(selector, action) { 12673 var data = $(this).data(); 12674 var selector = data.selector; 12675 var action = data.controller_action; 12676 var cell_id = data.cell_id; 12677 12678 $(selector + ' .tabnav .tabnav__tab').removeClass('selected'); 12679 $(this).addClass('selected'); 12680 12681 $('.switch_widget_view').hide(); 12682 12683 $.post('/user_dashboard/' + action, {method: data.action, cell_id: cell_id} , function(response) { 12684 $('#' + data.name).html(response); 12685 list_widget_load_carousel(selector); 12686 }); 12687} 12688 12689function list_widget_content2(selector, action) { 12690 var data = $(this).data(); 12691 var selector = data.selector; 12692 var url = data.url; 12693 var cell_id = data.cell_id; 12694 12695 $(selector + ' .tabnav .tabnav__tab').removeClass('selected'); 12696 $(this).addClass('selected'); 12697 12698 $('.switch_widget_view').hide(); 12699 12700 reset_tabs(selector) 12701 tabnav_adjustment(selector); 12702 12703 if( Excalibur.Mobile.is_mobile_app() && (Excalibur.$view.hasClass('offline-mode') || !navigator.onLine) ) 12704 $.get( (url + '.html'), function(response){ 12705 $('#' + data.name).html(response); 12706 list_widget_load_carousel(selector); 12707 }); 12708 else 12709 $.post(url, {method: data.action, cell_id: cell_id} , function(response) { 12710 $('#' + data.name).html(response); 12711 list_widget_load_carousel(selector); 12712 }); 12713} 12714 12715function list_widget_load_carousel(selector) { 12716 if (!$(selector).hasClass('expanded_widget')) { 12717 selector = selector + " .full_width_slider.swiper-container"; 12718 12719 if ($(selector).length === 0) { 12720 selector = ".full_width_widget .full_width_slider.swiper-container"; 12721 } 12722 12723 create_full_width_carousel(selector); 12724 } 12725} 12726 12727function widget_classes_initiate(method, view) { 12728 $.each($('.switch_widget_view'), function(i, v) { 12729 $(v).data('method', method); 12730 }); 12731 12732 if (typeof view !== 'undefined') { 12733 $('.switch_widget_view').hide(); 12734 12735 if (view == 'list') { 12736 $('.switch_widget_view.tile_view').css('display', 'block'); 12737 } else if (view == 'tile') { 12738 $('.switch_widget_view.list_view').css('display', 'block'); 12739 } 12740 } 12741} 12742 12743function widget_classes_paginate_catch() { 12744 var container = $('#ClassListsWidget'); 12745 12746 container.find('.search-navigation a').on('click', function(e) { 12747 e.preventDefault(); 12748 $.get($(this).attr('href'), {ajax: true}, function(response) { 12749 container.find('.ajaxLoadedContent').html(response); 12750 }); 12751 }); 12752} 12753 12754function toggle_classes_widget_search(el, method) { 12755 var container = $('#ClassListsWidget'); 12756 var input = container.find('input.quick_search');
12757 var search_wrapper = container.find('.optionsRibbonClassesWidget'); 12758 12759 if (search_wrapper.is(':visible')) { 12760 search_wrapper.hide(); 12761 input.val(''); 12762 $.get('/user_dashboard/get_classes_list', {method: method, ajax: true, phrase: ''}, function(response) { 12763 container.find('.ajaxLoadedContent').html(response); 12764 }); 12765 } else { 12766 search_wrapper.show(); 12767 } 12768} 12769 12770function toggle_classes_widget_search2(el, method) { 12771 var container = $('#ClassListsWidget'); 12772 var input = container.find('input.quick_search'); 12773 var search_wrapper = container.find('.optionsRibbonClassesWidget'); 12774 12775 if (search_wrapper.is(':visible')) { 12776 search_wrapper.hide(); 12777 input.val(''); 12778 $.get('/class_lists_widget/' + method, {ajax: true, phrase: ''}, function(response) { 12779 container.find('.ajaxLoadedContent').html(response); 12780 }); 12781 } else { 12782 search_wrapper.show(); 12783 } 12784} 12785 12786function toggle_classes_widget_search2(el, method) { 12787 var container = $('#ClassListsWidget'); 12788 var input = container.find('input.quick_search'); 12789 var search_wrapper = container.find('.optionsRibbonClassesWidget'); 12790 12791 if (search_wrapper.is(':visible')) { 12792 search_wrapper.hide(); 12793 input.val(''); 12794 $.get('/class_lists_widget/' + method, {ajax: true, phrase: ''}, function(response) { 12795 container.find('.ajaxLoadedContent').html(response); 12796 }); 12797 } else { 12798 search_wrapper.show(); 12799 } 12800} 12801 12802function widget_classes_search(method) { 12803 var container = $('#ClassListsWidget'); 12804 var input = container.find('input.quick_search'); 12805 12806 input.keyup(function(e) { 12807 typewatch(function() { 12808 $.get('/user_dashboard/get_classes_list', {method: method, ajax: true, phrase: input.val()}, function(response) { 12809 container.find('.ajaxLoadedContent').html(response); 12810 }); 12811 }, 1000); 12812 }); 12813} 12814 12815function widget_classes_search2(method) { 12816 var container = $('#ClassListsWidget'); 12817 var input = container.find('input.quick_search'); 12818 12819 input.keyup(function(e) { 12820 typewatch(function() { 12821 $.get('/class_lists_widget/' + method, {ajax: true, phrase: input.val()}, function(response) { 12822 container.find('.ajaxLoadedContent').html(response); 12823 }); 12824 }, 1000); 12825 }); 12826} 12827 12828function widget_classes_search2(method) { 12829 var container = $('#ClassListsWidget'); 12830 var input = container.find('input.quick_search'); 12831 12832 input.keyup(function(e) { 12833 typewatch(function() { 12834 $.get('/class_lists_widget/' + method, {ajax: true, phrase: input.val()}, function(response) { 12835 container.find('.ajaxLoadedContent').html(response); 12836 }); 12837 }, 1000); 12838 }); 12839} 12840 12841function widget_users_paginate_catch() { 12842 var container = $('#UserListsWidget'); 12843 12844 container.find('.search-navigation a').on('click', function(e) { 12845 e.preventDefault(); 12846 $.get($(this).attr('href'), {ajax: true}, function(response) { 12847 container.find('.ajaxLoadedContent').html(response); 12848 }); 12849 }); 12850} 12851 12852function toggle_users_widget_search(el, method) { 12853 var container = $('#UserListsWidget'); 12854 var input = container.find('input.quick_search'); 12855 var search_wrapper = container.find('.optionsRibbonUsersWidget'); 12856 12857 if (search_wrapper.is(':visible')) { 12858 search_wrapper.hide(); 12859 input.val(''); 12860 $.get('/user_lists_widget/' + method, {ajax: true, phrase: ''}, function(response) { 12861 container.find('.ajaxLoadedContent').html(response); 12862 }); 12863 } else { 12864 search_wrapper.show(); 12865 } 12866} 12867 12868function widget_users_search(method) { 12869 var container = $('#UserListsWidget'); 12870 var input = container.find('input.quick_search'); 12871 12872 input.keyup(function(e) { 12873 typewatch(function() { 12874 $.get('/user_lists_widget/' + method, {ajax: true, phrase: input.val()}, function(response) { 12875 container.find('.ajaxLoadedContent').html(response); 12876 }); 12877 }, 1000); 12878 }); 12879} 12880 12881function switch_widget_view() { 12882 var data = $(this).data(); 12883 $.post('/user_dashboard/change_classes_widget_view', {view: data.view}, function(response) { 12884 $.get('/user_dashboard/get_classes_list', {method: data.method, cell_id: data.cell_id}, function(response) { 12885 $('#ClassListsWidget').html(response); 12886 }); 12887 }); 12888} 12889 12890function switch_widget_view2() { 12891 var data = $(this).data(); 12892 $.post('/class_lists_widget/toggle_view', {view: data.view}, function(response) { 12893 $.get('/class_lists_widget/' + data.method, {cell_id: data.cell_id}, function(response) { 12894 $('#ClassListsWidget').html(response); 12895 }); 12896 }); 12897} 12898 12899// transfer students 12900 12901function transfer(element) { 12902 var selected = $('input[name="select[]"]:checked'); 12903 var select_all = $('input[name="select_all"]').val() == "true"; 12904 12905 if (selected.length == 0) { 12906 $.alert({content: "No items were selected."}); 12907 } else { 12908 var url = $(element).attr('href') + "?"; 12909 var selected_array = []; 12910 12911 if (select_all) { 12912 url = url + 'select_all=true&';
12913 } 12914 12915 $.each(selected, function(i, v) { 12916 selected_array.push("select[]=" + $(v).attr('id')); 12917 }); 12918 12919 url = url + selected_array.join('&'); 12920 12921 $.facebox({'ajax' : url}); 12922 } 12923} 12924 12925function remove_slide_filter() { 12926 var data = $(this).data(); 12927 12928 // container 12929 var slide_title_element = $('.slide-' + data.id + ' a.slide_title'); 12930 var container_type = slide_title_element.data('container_type'); 12931 var container_id = slide_title_element.data('id'); 12932 12933 var panel = $('.section_carousel_panel_' + data.id); 12934 12935 $.post('/banner_slide/remove_slide_filter/' + container_id, {slide_id: data.id, container_type: container_type}, function(response) { 12936 if (response.status == 'ok') { 12937 var manager = window.conditionalFilterManager; 12938 12939 panel.find('.add_filter').show(); 12940 panel.find('.has_filter').hide(); 12941 panel.find('.has_filter .filter_conditions').text(''); 12942 12943 // the slide has an add and an edit trigger, each with its own registration holding the deleted filter id 12944 if (manager) { 12945 manager.filterIds().forEach(function(id) { 12946 if (panel.find('#' + id).length) { 12947 var options = manager.filterOptions(id); 12948 options.filter_id = null; 12949 manager.setFilterOptions(id, options); 12950 } 12951 }); 12952 } 12953 } else { 12954 console.log(response.message); 12955 } 12956 }); 12957} 12958 12959function set_logged_out_cookie() { 12960 sessionStorage.setItem("logged_out_session", "true"); 12961} 12962 12963function login_as_stealth_mode(element) { 12964 var form = $(element).parents('form#user_log_in'); 12965 form.find('input[name=update_history]').remove(); 12966 form.submit(); 12967} 12968 12969function toggle_mobile_app_use_overwritten(checkbox, id) { 12970 $.post('/branded_mobile_app_support/set_use_overwritten_fields/' + id, {value: checkbox.checked}); 12971} 12972 12973// onboarding schools 12974 12975function onboard_wizard(id, next) { 12976 if ($('#facebox_overlay').length == 0) { 12977 $('body').append('<div id="facebox_overlay" class="facebox_overlayBG"></div>'); 12978 } 12979 12980 if ($('#fullscreen_msg_holder').length > 0) { 12981 $('#fullscreen_msg_holder').remove(); 12982 } 12983 12984 $('.facebox_overlayBG').css('opacity','0.4'); 12985 $('body').addClass('no-scroll blur_site'); 12986 $('body').append('<div id="fullscreen_msg_holder" class="fullscreen_progress"><div id="fullscreen_msg" role="dialog" tabindex="-1"></div></div>'); 12987 12988 let now = new Date(); 12989 let time = now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate() + ' ' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds(); 12990 12991 $.get("/school/onboard/" + id, {time: time}, function(data) { 12992 $('#fullscreen_msg').html(data).focus(); 12993 12994 if (next) { 12995 // language was selected 12996 $('#onboarding_save_language').trigger('click'); 12997 } 12998 12999 $(".get_started_wizard input[name=language]").change(function() { 13000 if (onboarding_language_id == parseInt($(this).val())) { 13001 $.each(onboarding_active_buttons, function(i,v) { 13002 if (v != 'panel1') { 13003 $("button#" + v).removeAttr('disabled'); 13004 } 13005 }); 13006 13007 $.each(onboarding_completed_buttons, function(i,v) { 13008 if (v != 'panel1') { 13009 $("button#" + v).addClass('completed'); 13010 } 13011 }); 13012 } else { 13013 $.each(onboarding_active_buttons, function(i,v) { 13014 if (v != 'panel1') { 13015 $("button#" + v).attr('disabled', true); 13016 } 13017 }); 13018 13019 $.each(onboarding_completed_buttons, function(i,v) { 13020 if (v != 'panel1') { 13021 $("button#" + v).removeClass('completed'); 13022 } 13023 }); 13024 } 13025 }) 13026 13027 $(".get_started_wizard input[name=theme]").change(function() { 13028 $.get('/school/get_stylesheet/' + id, {name: $(this).val()}, function(response) { 13029 $("<link/>", {rel: "stylesheet", type: "text/css", href: response.url}).appendTo("head"); 13030 }) 13031 }) 13032 13033 $('.get_started_wizard .single_file_upload_button').click(function() { 13034 var interval = setInterval(function() { 13035 if ($('.get_started_wizard .uploader-list input[type=\'hidden\']').length > 0) { 13036 var next_button = $('.get_started_wizard .wizard_content').find('button[panel-id="panel6"][data-next_tab="finish"]'); 13037 next_button.html(next_button.data('next_text')); 13038 clearInterval(interval); 13039 } 13040 }, 1500); 13041 }) 13042 }); 13043} 13044 13045function onboarding_save_language() { 13046 var data = $(this).data(); 13047 var current_language = data.current_language; 13048 var selected_language = $(this).parents('form').find('input[name=language]:checked').val(); 13049 13050 if (current_language == selected_language) { 13051 wizard_nav_click(this); 13052 } else { 13053 let now = new Date(); 13054 let time = now.getFullYear() + '-' + (now.getMonth() + 1) + '-' + now.getDate() + ' ' + now.getHours() + ':' + now.getMinutes() + ':' + now.getSeconds(); 13055 13056 $.post('/select_language/submit_language', {language: selected_language, time: time, aja
13056x: true}, function(response) { 13057 onboard_wizard(response.school_id, true); 13058 }); 13059 } 13060} 13061 13062function onboarding_yourself_data() { 13063 onboarding_wizzard_data.school.country = $("#school_country").val(); 13064 onboarding_wizzard_data.school.time_zone = $("#school_time_zone").val(); 13065 13066 if ($("#school_state").is(':visible')) { 13067 onboarding_wizzard_data.school.state = $("#school_state").val(); 13068 } 13069 13070 if ($("#school_other_state").is(':visible')) { 13071 onboarding_wizzard_data.school.state = $("#school_other_state").val(); 13072 } 13073 13074 onboarding_wizzard_data.marketing.role = $("#role_name").val(); 13075 13076 if ($("#role_detail").is(':visible')) { 13077 onboarding_wizzard_data.marketing.role_detail = $("#role_detail").val(); 13078 } 13079 13080 onboarding_wizzard_data.marketing.channel = $("#marketing_channel").val(); 13081 onboarding_wizzard_data.marketing.channel_details = $("#marketing_channel_detail").val(); 13082} 13083 13084function onboarding_organization_data() { 13085 onboarding_wizzard_data.marketing.industry = $("#organization_industry").val(); 13086 onboarding_wizzard_data.marketing.audience = $("#organization_audience").val(); 13087 onboarding_wizzard_data.marketing.plan = $("#organization_plans").val(); 13088 onboarding_wizzard_data.marketing.training = $("#marketing_training").val(); 13089 onboarding_wizzard_data.marketing.training_detail = $("#marketing_training_detail").val(); 13090} 13091 13092function onboarding_theme_data() { 13093 if($(document.body).hasClass('evo')) { 13094 onboarding_wizzard_data.selected_evo_theme_colors = window.selected_evo_theme_colors; 13095 }else { 13096 onboarding_wizzard_data.theme = $("[name=theme]:checked").val(); 13097 } 13098} 13099 13100function onboarding_logo_data() { 13101 if ($(".get_started_wizard #UploaderWrapper input#photo").length > 0) { 13102 onboarding_wizzard_data.logo = $(".get_started_wizard #UploaderWrapper input#photo").val(); 13103 } else { 13104 onboarding_wizzard_data.logo = null; 13105 } 13106} 13107 13108// validate 13109 13110function onboarding_validate() { 13111 if (onboarding_tab == 'yourself' && ($("#role_name").val() == '' || $("#marketing_channel").val() == '' || $("#school_country").val() == '' || ($("#school_state").val() == '' && $("#school_other_state").val() == '') || $("#school_time_zone").val() == '')) { 13112 return false; 13113 } 13114 13115 if (onboarding_tab == 'organization' && ($("#organization_industry").val() == "" || $("#organization_audience").val() == '' || $("#marketing_training").val() == '' || $("#organization_plans").val() == '')) { 13116 return false; 13117 } 13118 13119 return true; 13120} 13121 13122function update_data() { 13123 switch(onboarding_tab) { 13124 case 'yourself': 13125 onboarding_yourself_data(); 13126 break; 13127 case 'organization': 13128 onboarding_organization_data(); 13129 break; 13130 case 'theme': 13131 onboarding_theme_data(); 13132 break; 13133 case 'logo': 13134 onboarding_logo_data(); 13135 break; 13136 } 13137} 13138 13139function wizard_nav_click(element) { 13140 var data = $(this).data(); 13141 13142 if (data.direction != 'previous') { 13143 if (!onboarding_validate()) { 13144 13145 $.alert({content: "Please complete all the mandatory fields"}); 13146 return false; 13147 } 13148 } 13149 13150 update_data(); 13151 13152 var element = element || this; 13153 var new_panel_id = element.attr('panel-id'); 13154 var wizard_nav_item = $('#' + new_panel_id); 13155 var wizard_panel = element.closest('.wizard_wrapper'); 13156 13157 wizard_nav_item.siblings().removeClass('selected').attr("aria-selected","false"); 13158 wizard_nav_item.prev().addClass('completed'); 13159 wizard_nav_item.addClass('selected').attr("aria-selected","true").prop("disabled", false); 13160 13161 wizard_panel.find('.wizard_content[aria-hidden="false"]').attr("aria-hidden","true"); 13162 wizard_panel.find('.wizard_content[aria-labelledby="' + new_panel_id + '"]').attr('aria-labelledby',new_panel_id).attr("aria-hidden","false"); 13163 13164 onboarding_tab = $(element).data('next_tab'); 13165 13166 onboarding_active_buttons = []; 13167 $.each($('.wizard_nav button'), function(i,v) { 13168 if(!$(this).is(':disabled')) { 13169 onboarding_active_buttons.push($(this).attr('id')); 13170 } 13171 }); 13172 13173 onboarding_completed_buttons = []; 13174 $.each($('.wizard_nav button.completed'), function(i,v) { 13175 onboarding_completed_buttons.push($(this).attr('id')); 13176 }); 13177} 13178 13179function change_marketing_channel(value) { 13180 $('.marketing_channel_detail_cell, .marketing_channel_detail_cell span').hide(); 13181 13182 if ($('.marketing_channel_detail_cell span[data-value="' + value + '"]').length) { 13183 $('.marketing_channel_detail_cell, .marketing_channel_detail_cell span[data-value="' + value + '"]').show(); 13184 } 13185} 13186 13187function select_single_wizard_item(element, value) { 13188 if ($(element + ' span[data-value="' + value + '"]').length) { 13189 $(element).show(); 13190 } else { 13191 $(element).hide(); 13192 } 13193} 13194 13195function wizard_complete(id) { 13196 var data = $(this).data(); 13197 13198 $.post('/school/onboard_save/' + data.school_id, onboarding_wizzard_data, function(response) { 13199 if (response.status == 'ok') { 13200 location.reload(); 13201 } else { 13202 $.alert({content: response.error}); 13203 } 13204 }); 13205} 13206 13207function stackedSinglePickerCallback(input, selector, url) { 13208 var value = $(input).val(); 13209 var name = $('.facebox-content ' + selector); 13210 13211 // fix for the hidden editor on facebox stack comeback 13212 $('#facebox .mce-tinymce').show(); 13213 13214 if (window.pickerSelectedId && typeof(window.pickerSelectedId) != 'undefined' && window.pickerSelectedId != value) { 13215 $(input).val(window.pickerSelectedId); 13216 $(".facebox-content .single_file_upload_button").html("<i class=\"edit\"></i>" + change_text); 13217 name.attr('style','float:left;padding:0;margin:6px 16px 0 0'); 13218 13219 if (name.find('a').length == 0) { 13220 name.append("<a href=\"" + url + "/" + window.pickerSelectedId + "\">" + window.pickerSelectedName + "</a>"); 13221 } else { 13222 name.find('a').attr('href', url + "/" + window.pickerSelectedId); 13223 name.find('a').text(window.pickerSelectedName); 13224 } 13225 13226 window.pickerSelectedId = null; 13227 window.pickerSelectedName = null; 13228 } 13229} 13230 13231function stackedClassSectionPickerCallback(class_id, class_name, selector, url) { 13232 var class_id = $(class_id); 13233 var name = $('.facebox-content ' + selector); 13234 13235 if (window.pickerSelectedId && typeof(window.pickerSelectedId) != 'undefined' && window.pickerSelectedId != class_id.val()) { 13236 class_id.val(window.pickerSelectedId); 13237 $(class_name).val(window.pickerSelectedName); 13238 $(".facebox-content .single_file_upload_button").html("<i class=\"edit\"></i>" + change_text); 13239 name.attr('style','float:left;padding:0;margin:6px 16px 0 0'); 13240 13241 if (name.find('a').length == 0) { 13242 name.append("<a href=\"" + url + "/" + window.pickerSelectedId + "\">" + window.pickerSelectedName + "</a>"); 13243 } else { 13244 name.find('a').attr('href', url + "/" + window.pickerSelectedId); 13245 name.find('a').text(window.pickerSelectedName); 13246 } 13247 13248 window.pickerSelectedId = null; 13249 window.pickerSelectedName = null; 13250 } 13251 13252 // fix for the hidden editor on facebox stack comeback 13253 $('#facebox .mce-tinymce').show(); 13254} 13255 13256// network admin login 13257 13258function login_to_site(school_id, extra_params) { 13259 if (school_id) { 13260 var url = '/network/visit?school_id=' + school_id.toString(); 13261 13262 if (extra_params) { 13263 url += extra_params; 13264 } 13265 13266 window.location.href = url; 13267 } else{ 13268 show_error('Invalid site was selected.'); 13269 } 13270} 13271 13272// init panopto login 13273 13274function init_panopto_login(data) { 13275 execute_panopto_login(data); 13276 13277 $(window).on('loadcomplete', function () { 13278 execute_panopto_login(data); 13279 }) 13280} 13281 13282function execute_panopto_login(data) { 13283 const panopto_videos = $('.panoptoVideo'); 13284 const json = JSON.parse(atob(data.replace(/_/g, '/').replace(/-/g, '+'))); 13285 13286 if (panopto_videos.length > 0 || json.silent_login) { 13287 $('#panoptoLoginElement').remove(); 13288 13289 const loginElement = document.createElement('div'); 13290 loginElement.id = 'panoptoLoginElement'; 13291 loginElement.style.display = 'none'; 13292 13293 const iframe = document.createElement('iframe'); 13294 iframe.id = 'panoptoLoginIframe'; 13295 iframe.name = 'panoptoLoginIframe'; 13296 loginElement.appendChild(iframe); 13297 13298 const form = document.createElement('form'); 13299 form.id = 'panoptoLoginForm'; 13300 form.name = 'panoptoLoginForm'; 13301 form.action = json.launch_url; 13302 form.method = 'post'; 13303 form.enctype = 'application/x-www-form-urlencoded'; 13304 form.target = 'panoptoLoginIframe'; 13305
13306 Object.entries(json.launch_data).forEach(([key, value]) => { 13307 const input = document.createElement('input'); 13308 input.type = 'hidden'; 13309 input.name = key; 13310 input.value = value; 13311 form.appendChild(input); 13312 }); 13313 13314 loginElement.appendChild(form); 13315 document.body.appendChild(loginElement); 13316 13317 if (!json.silent_login) { 13318 // Load videos after the launch iframe loads 13319 iframe.addEventListener('load', function() { 13320 panopto_videos.each(function(_idx, video) { 13321 video.src = video.dataset.src; 13322 }); 13323 }); 13324 } 13325 13326 // Submit the form 13327 form.submit(); 13328 } 13329} 13330 13331function lesson_period_date_changed(year, month, day) { 13332 period_date_changed(year, month, day, "lesson_period_number_select" ) 13333} 13334 13335function class_session_period_date_changed(year, month, day) { 13336 period_date_changed(year, month, day, "class_session_period_number_select" ) 13337} 13338 13339function period_date_changed(year, month, day, period_select_class_name) { 13340 let period_options = $("." + period_select_class_name + " > option") 13341 13342 // enable all options 13343 period_options.each(function() { 13344 $(this).removeAttr("disabled"); 13345 }); 13346 13347 if(year !== '') { 13348 let new_date = new Date(year, month-1, day); 13349 13350 let disabled_options = disabled_periods_for_wday[new_date.getDay()]; 13351 if(disabled_options.length > 0){ 13352 let first_available = true; 13353 $("." + period_select_class_name).val(''); 13354 13355 period_options.each(function() { 13356 let value = $(this).val(); 13357 if(value !== ''){ 13358 if(disabled_options.includes(parseInt(value))){ // disable any option which is disabled for this date 13359 $(this).attr("disabled", "disabled"); 13360 } else if(first_available){ // select the first option which is not disabled 13361 $("." + period_select_class_name).val(value); 13362 first_available = false; 13363 } 13364 } 13365 }); 13366 } 13367 } 13368} 13369 13370// proficiency edit 13371 13372function proficiency_tag_edit() { 13373 $('.proficiency_edit').hide(); 13374 $('.proficiency_edit_cancel').show(); 13375 $('.add_more_proficiency_tag_').show(); 13376 $('span[class*=proficiency_tag_] a').css('display', 'inline'); 13377} 13378 13379function proficiency_tag_edit_cancel() { 13380 $('.proficiency_edit').show(); 13381 $('.proficiency_edit_cancel').hide(); 13382 $('.add_more_proficiency_tag_').hide(); 13383 $('span[class*=proficiency_tag_] a').hide(); 13384} 13385 13386function proficiency_tag_remove(element) { 13387 $.confirm({ 13388 content: 'Are you sure you want to delete the proficiency?', 13389 confirm: function() { 13390 let el = $(element); 13391 let elements_count = $('span[class^=proficiency_tag_]').length; 13392 13393 $.post(el.attr('href'), function(response) { 13394 el.parent('span').remove(); 13395 13396 if (elements_count == 1) { 13397 $('.add_more_proficiency_tag_').hide(); 13398 $('.proficiency_edit_cancel').hide(); 13399 $('.proficiency_add').show(); 13400 } 13401 }); 13402 } 13403 }); 13404} 13405 13406 13407// security roles 13408 13409function show_permission_model_columns(link, model_name) { 13410 if($(link).attr('aria-expanded') === 'true'){ 13411 $(link).attr('aria-expanded', 'false'); 13412 $(link).find('i').attr('class', 'arrowRight'); 13413 $('#permissions_' + model_name).hide(); 13414 }else { 13415 $(link).attr('aria-expanded', 'true'); 13416 $(link).find('i').attr('class', 'arrowDown'); 13417 $('#permissions_' + model_name).show(); 13418 } 13419} 13420 13421function display_filter_form_data(dropdown) { 13422 $.get('/restricted_roles/get_filter?filter_type=' + dropdown.value, function (html) { 13423 $('#restricted_role_filter').html(html); 13424 }) 13425} 13426// Adblocker detection 13427 13428function show_adblocker_warning(title, content) { 13429 if(typeof(PageAnalytics) === 'undefined') { 13430 $.alert({title: title, content: content}); 13431 } 13432} 13433 13434//bug_filters 13435function add_bug_filter(operation) { 13436 prompt = "Add filter for " + operation; 13437 $.confirm({ 13438 content: prompt, 13439 confirm: function() { 13440 url = '/bugs/submit_filter?filter=' + operation; 13441 $.get(url, function(response) {}); 13442 location.reload(true); 13443 }, 13444 cancel: function() { 13445 } 13446 }); 13447} 13448 13449// recommendations ajax 13450 13451function load_recommendation_action_via_ajax(el) { 13452 let location = $(el).attr('href'); 13453 let action_type = (location.includes('dismiss') ? 'dismiss' : 'restore'); 13454 let selected_tab = $('.recommendations_widget .tabnav a.selected'); 13455 let not_selected_tab = $('.recommendations_widget .tabnav a:not(.selected)'); 13456 13457 $.confirm({ 13458 confirm: function() { 13459 $.get(location, function(response) { 13460 let method = selected_tab.data('action'); 13461 let selected_count = parseInt(selected_tab.find('span').text()); 13462 let not_selected_count = parseInt(not_selected_tab.find('span').text()); 13463 13464 if (action_type == 'restore' && not_selected_count == 1) { 13465 selected_tab.removeClass('selected'); 13466 not_selected_tab.addClass('selected'); 13467 not_selected_tab.addClass('hide'); 13468 method = not_selected_tab.data('action'); 13469 selected_tab.hide(); 13470 } else if (action_type == 'dismiss' && not_selected_count == 0) { 13471 not_selected_tab.show(); 13472 } 13473 13474 // update counters 13475 selected_tab.find('span').text(selected_count - 1); 13476 not_selected_tab.find('span').text(not_selected_count + 1); 13477 13478 // update content 13479 widget_load_content_via_ajax('recommendations_widget_content', recommendations_class_name, recommendations_load_content_method, {cell_id: recommendations_cell_id, method: method}); 13480 }); 13481 } 13482 }); 13483} 13484 13485// scale questions 13486 13487function set_scale_type(type) { 13488 let labels = $("div.labels"); 13489 13490 if (type == 'star') { 13491 labels.hide(); 13492 labels.find('input').val(''); 13493 } else { 13494 labels.show(); 13495 } 13496} 13497 13498// matrix questions 13499 13500function set_matrix_options(type, limit) { 13501 let number = $("#question_" + type + "s").val(); 13502 13503 for (let i = 1; i <= limit; i++) { 13504 let element = $('p.matrix_' + type + '_label_' + i); 13505 13506 if (i <= number) { 13507 element.show(); 13508 } else { 13509 element.hide(); 13510 element.find('input').val(''); 13511 } 13512 } 13513} 13514 13515// unlock next lesson when lesson/section completed 13516 13517function unlock_next_lesson_poll(class_id, lesson_id, student_id) { 13518 var url = '/student_lesson/check_lesson_status?id=' + class_id + '&lesson_id=' + lesson_id + '&student_id=' + student_id; 13519 var unlock_next_lesson_poll_interval = setInterval(function () { 13520 $.get(url, function (response) { 13521 if (response.completed) { 13522 $.each($('[id="dynamic_button"]'), function (key, button) { 13523 var next_url = $(button).data('next_url'); 13524 var next_text = $(button).data('next_text'); 13525 $(button).removeClass('locked').attr('href', next_url); 13526 $(button).text(next_text); 13527 $(button).find('i').replaceWith('<img src="/images/icons/large-arrow-white.svg" alt="" />'); 13528 }); 13529 13530 clearInterval(unlock_next_lesson_poll_interval); 13531 } 13532 }); 13533 }, 30000); 13534 13535 $(window).on('beforexload', function () { 13536 clearInterval(unlock_next_lesson_poll_interval); 13537 }); 13538} 13539 13540// close SCORM iframe 13541 13542function cors_close_scorm_embed(redirect_to) { 13543 if ((typeof redirect_to !== 'undefined') && (redirect_to !== '')) { 13544 window.addEventListener("message", function(event) { 13545 var data = JSON.parse(event.data); 13546 13547 if(/scorm_lms_finish_ended/.test(event.data)){ 13548 if (typeof data.scorm_lms_finish_ended != 'undefined') { 13549 document.location = redirect_to; 13550 } 13551 } 13552 }); 13553 } 13554 13555 var scorm_iframe = document.getElementById('scorm_iframe'); 13556 13557 if (scorm_iframe) { 13558 scorm_iframe.contentWindow.postMessage('{"cors_close_scorm_embed": true}', '*'); 13559 } 13560} 13561 13562function init_scorm_page_listener() { 13563 $(window).off('beforexload.scorm').on('beforexload.scorm', function () { 13564 cors_close_scorm_embed(''); 13565 $(window).off('beforexload.scorm'); 13566 }); 13567} 13568 13569// session change 13570 13571function session_change_update() { 13572 $('input[type=radio][id^=children_]').on('change', function() { 13573 let element = $('.module_course_header .modern_module_row a.modern_module_wrap'); 13574 let url = element.attr('href'); 13575 let match = url.match(/class_id=[0-9]+&/g); 13576 element.attr('href', url.replace(match, 'class_id=' + $(this).val() + '&')); 13577 }); 13578} 13579 13580// recommendations 13581
13582function dismiss_recommendation(event, id, goal_id, recommendation_id) { 13583 event.stopPropagation(); 13584 13585 $.confirm({ 13586 confirm: function() { 13587 $.post('/learning_goal/dismiss_recommendation/' + goal_id, {recommendation_id: recommendation_id}, function(response) { 13588 let count = $('.skills_widget .headingLinkWrap').find('a[data-action="get_recommendations"] span'); 13589 count.text(parseInt(count.text()) - 1); 13590 $('#' + id).remove(); 13591 }) 13592 } 13593 }) 13594} 13595 13596// resource catalog inifinte scroll 13597 13598var resources_scroll_stop = false; 13599var resource_scroll_options; 13600var resource_ajax_view; 13601var resource_ajax_wrapper; 13602 13603function scroll_for_more_resources() { 13604 $(window).scroll(function () { 13605 if ($('#centreColumn .leftColumn.resources_catalog').length != 0 && !resources_scroll_stop && resource_scroll_options != false) { 13606 if ($(window).scrollTop() >= $(document).height() - $(window).height() - 50) { 13607 resources_scroll_stop = true; 13608 13609 let data = clean_args_for_null(JSON.parse(resource_scroll_options)); 13610 data.ajax_request = true; 13611 data.partial_view = resource_ajax_view; 13612 13613 $.post('/library', data, function(html) { 13614 $(resource_ajax_wrapper).find('script').remove(); 13615 $(resource_ajax_wrapper).find('.resource_catalog_loader').remove(); 13616 $(resource_ajax_wrapper).append(html); 13617 resources_scroll_stop = false; 13618 }); 13619 } 13620 } 13621 }); 13622} 13623 13624function resources_go_to_details(url) { 13625 window.location = url; 13626} 13627 13628function clean_args_for_null(args) { 13629 for (var attribute in args) { 13630 if (args[attribute] === null || args[attribute] === undefined) { 13631 delete args[attribute]; 13632 } 13633 } 13634 return args; 13635} 13636 13637function search_simple_filter() { 13638 var url = window.location.pathname; 13639 13640 $('#filter').keyup(function(e) { 13641 typewatch(function() { 13642 var payload = {ajax_request: true}; 13643 var value = $("#filter").val().trim(); 13644 13645 if (!(value === undefined) && !(value == "")) { 13646 payload["filter"] = value; 13647 } 13648 13649 $.get(url, payload, function(html) { 13650 $('#SearchResultsWrapper').html(html); 13651 to_load(); 13652 }); 13653 }, 1000); 13654 }); 13655} 13656 13657function init_simple_ordering() { 13658 var elements = document.getElementById('SearchResultsWrapper').querySelectorAll('a.sort-by, a.asc, a.desc, a.no-loader'); 13659 13660 elements.forEach( (element) => { 13661 element.classList.add('bypass-ajax'); 13662 13663 element.addEventListener("click", function (e) { 13664 e.preventDefault(); 13665 13666 $.get(element.href, {ajax_request: true}, function(html) { 13667 $('#SearchResultsWrapper').html(html); 13668 to_load(); 13669 }); 13670 13671 }, true); 13672 }); 13673} 13674 13675function set_days_before_adding_attendance(dropdown, class_id) { 13676 ajax_request('/teacher_attendance/set_days_before_adding_attendance/' + class_id + '?value=' + encodeURIComponent(dropdown.value)); 13677} 13678 13679 13680function disable_and_submit_form_on_click() { 13681 this.form().submit(); 13682 this.prop('disabled', true); 13683} 13684 13685function confirm_grade_release_change(el, initial_value, create) { 13686 var elem = $(el); 13687 13688 if (create == true) { 13689 setTimeout(function() {elem.prop('checked', true);}, 200); 13690 } else if (initial_value == 'Manual' && elem.val() == 'Instant') { 13691 $.confirm({ 13692 content: "Changing this option will release all your given grades on save!", 13693 confirm: function() { 13694 console.log($(el)) 13695 elem.prop('checked', true); 13696 } 13697 }); 13698 } else { 13699 setTimeout(function() {elem.prop('checked', true);}, 200); 13700 } 13701} 13702 13703// configure class 13704 13705function set_bug_filter(bug_history_id, checkbox) { 13706 ajax_request('/bugs/set_filter/' + bug_history_id + '?value=' + (checkbox.checked ? 'true' : 'false')); 13707} 13708 13709/** 13710 * Check for empty string including spaces and new lines also strip out html <p> tag 13711 * @param string (text or html) 13712 * @return {boolean} true if string is empty 13713 */ 13714function isStringEmpty(string) { 13715 var string_has_html = string.split('').map(c =>c.trim()).join(''); 13716 var string_text_remove_p = string_has_html.replace('<p>','').replace('</p>',''); 13717 return (string_text_remove_p == '')? true : false; 13718} 13719 13720 13721// copilot 13722 13723function add_competencies_in_place() { 13724 let wrapper = $('.selected_competencies'); 13725 13726 $.each(window.copilotSelectedCompetencies, function(i, v) { 13727 let id = v[0].split(',')[0]; 13728 let id_type = v[0]; 13729 let title = v[1]; 13730 13731 if ($('.copilot_competency_' + id).length == 0) { 13732 $.get('/curriculum/get_proficiencies/' + id, function(html) { 13733 wrapper.append('<div class="copilot_competency_' + id + '"><div><span>' + title + '</span> <a href="javascript:void(0)" class="delete_competency" onclick="delete_selected_competency(' + id + ')"><i class="blockCircle"></i></a></div><input type="hidden" name="options[competencies][ids][]" value="' + id_type + '"><br></div>'); 13734 wrapper.append('<div class="copilot_proficiencies_' + id + '">' + html + '</div>'); 13735 }) 13736 } 13737 }); 13738 13739 $("button[excalibur-click=\"Excalibur.Ai.start_confirm\"]").prop("disabled", false) 13740} 13741 13742function delete_selected_competency(id) { 13743 $('.copilot_proficiencies_' + id).remove(); 13744 $('.copilot_competency_' + id).remove(); 13745} 13746 13747function copilot_get_voices(show) { 13748 if (show) { 13749 $('.copilot_voices').show(); 13750 $('.copilot_voices_autoplay').show(); 13751 copilot_show_voices(false); 13752 } else { 13753 $('.copilot_voices').empty().hide(); 13754 $('.copilot_voices_autoplay').hide(); 13755 } 13756} 13757 13758function copilot_show_voices(selected_voice) { 13759 $.get('/copilot_voices', function(response) { 13760 if (response.status == 'ok') { 13761 $.each(response.voices, function(i, e) { 13762 var selected = selected_voice ? (selected_voice == e.id) : (i == 0); 13763 var html = '<div class="voice ' + e.id + '">'; 13764 html += '<input' + (selected ? ' checked="checked"' : '') + ' id="options_copilot_voice_' + e.id + '" name="options[copilot_voice]" type="radio" value="' + e.id + '">'; 13765 html += '<label for="options_copilot_voice_' + e.id + '">' + e.name + ' '; 13766 html += '<audio id="' + e.id + '" src="' + e.preview + '"></audio>'; 13767 html += '<a href="javascript:void(0)" class="play_voice" onclick="document.getElementById(\'' + e.id + '\').play()"><i class="audioPlay"></i></a>'; 13768 html += '<a href="javascript:void(0)" class="stop_voice" onclick="document.getElementById(\'' + e.id + '\').load()" style="display: none"><i class="audioStop"></i></a>'; 13769 html += '<br><span>' + e.description + '</span>'; 13770 html += '</label>'; 13771 13772 $('.copilot_voices').append(html); 13773 13774 voice_player(e.id); 13775 }); 13776 } 13777 }); 13778} 13779 13780function voice_player(id) { 13781 var wrapper = $('.' + id); 13782 var audio = wrapper.find('audio'); 13783 13784 audio[0].muted = false;
13785 13786 audio.on('ended loadstart', (event) => { 13787 wrapper.find('.play_voice').show(); 13788 wrapper.find('.pause_voice').hide(); 13789 wrapper.find('.stop_voice').hide(); 13790 }); 13791 13792 audio.on('play', (event) => { 13793 wrapper.find('.play_voice').hide(); 13794 wrapper.find('.pause_voice').show(); 13795 wrapper.find('.stop_voice').show(); 13796 }); 13797 13798 audio.on('pause', (event) => { 13799 wrapper.find('.play_voice').show(); 13800 wrapper.find('.pause_voice').hide(); 13801 }); 13802} 13803 13804function voice_autoplay(id) { 13805 setTimeout(function() { 13806 var element = document.getElementById(id); 13807 element.muted = false; 13808 element.play(); 13809 }, 2000); 13810} 13811 13812function crosscheck_apply_changes(controller, id, lesson_id, section_id) { 13813 $.confirm({ 13814 content: 'Warning: Are you sure you want to replace the content of the section?', 13815 confirm: function() { 13816 $.post('/' + controller + '/apply_crosscheck/' + id, {lesson_id: lesson_id, section_id: section_id}, function(response) { 13817 window.location.reload(); 13818 }); 13819 } 13820 }); 13821} 13822 13823function crosscheck_dismiss_changes(controller, id, lesson_id, section_id) { 13824 $.confirm({ 13825 content: 'Warning: If you dismiss the changes they are gone for good?', 13826 confirm: function() { 13827 $.post('/' + controller + '/dismiss_crosscheck/' + id, {lesson_id: lesson_id, section_id: section_id}, function(response) { 13828 window.location.reload(); 13829 }); 13830 } 13831 }); 13832} 13833 13834function crosscheck_dismiss_checked(controller, id, lesson_id, section_id) { 13835 $.post('/' + controller + '/dismiss_checked_message/' + id, {lesson_id: lesson_id, section_id: section_id}); 13836} 13837 13838function configure_copilot(attribute, checkbox, from) { 13839 window.location.href = '/copilot_admin/set_attribute?attribute=' + attribute + '&value=' + (checkbox.checked ? 'true' : 'false') + '&from=' + from; 13840} 13841 13842function insert_strong_password_regex(element) { 13843 $('#password_regex').val($(element).text()); 13844 $('#password_regex_description').val($(element).attr('title')); 13845} 13846 13847function password_strength_changed(element) { 13848 switch ($(element).val()) { 13849 case 'custom': 13850 $('#custom_password_regex').show(); 13851 break; 13852 13853 case 'weak': 13854 $('#custom_password_regex').hide(); 13855 break; 13856 13857 case 'strong_1': 13858 case 'strong_2': 13859 case 'strong_3': 13860 default: 13861 $('#custom_password_regex').hide(); 13862 $('#password_regex').val($(element).data('password_regex')); 13863 $('#password_regex_description').val($('label[for="' + element.id + '"]').text()); 13864 } 13865} 13866 13867function set_klass_lti_auto_create(element, class_id) { 13868 ajax_request('/class_configure/set_lti_auto_create/' + class_id + '?value=' + element.value); 13869} 13870 13871function disable_link_after_click(event, element) { 13872 if (element.getAttribute('data-clicked')) { 13873 // Prevent the default action if the link has already been clicked 13874 event.preventDefault(); 13875 } else { 13876 // Mark the link as clicked 13877 element.setAttribute('data-clicked', 'true'); 13878 } 13879} 13880 13881//function to switch permission grid to write mode 13882function toggleEdit(parentClass) { 13883 if(parentClass){ 13884 var parentElement = document.querySelector('.'+parentClass); 13885 var readMode = parentElement.querySelectorAll('.readModeContainer'); 13886 var writeMode = parentElement.querySelectorAll('.editModeContainer'); 13887 var saveButton = parentElement.querySelectorAll('#saveToggleButton'); 13888 var editButton = parentElement.querySelectorAll('#editToggleButton'); 13889 for (var i = 0; i < readMode.length; i++) { 13890 readMode[i].classList.toggle("permissionHideContainer"); 13891 } 13892 for (var j =0; j < writeMode.length; j++) { 13893 writeMode[j].classList.toggle("permissionHideContainer"); 13894 } 13895 editButton[0].style.display = 'none'; 13896 saveButton[0].style.display = 'block'; 13897 } 13898} 13899 13900//function to switch permission grid to read mode 13901function saveChanges(parentClass) { 13902 if(parentClass){ 13903 var parentElement = document.querySelector('.'+parentClass); 13904 var readMode = parentElement.querySelectorAll('.readModeContainer'); 13905 var writeMode = parentElement.querySelectorAll('.editModeContainer'); 13906 13907 var saveButton = parentElement.querySelectorAll('#saveToggleButton'); 13908 var editButton = parentElement.querySelectorAll('#editToggleButton'); 13909 13910 for (var i = 0; i < readMode.length; i++) { 13911 readMode[i].classList.toggle("permissionHideContainer"); 13912 } 13913 for (var j =0; j < writeMode.length; j++) {
13914 writeMode[j].classList.toggle("permissionHideContainer"); 13915 } 13916 editButton[0].style.display = 'block'; 13917 saveButton[0].style.display = 'none'; 13918 } 13919} 13920 13921function cancelChanges() { 13922 //cancel permission logic should go here. 13923 location.reload(); 13924} 13925 13926function disable_see_all_passwords(checkbox, confirm_msg) { 13927 $.confirm({ 13928 content: confirm_msg, 13929 confirm: function() { 13930 window.location.href = '/policies/disable_administrator_see_passwords'; 13931 }, 13932 cancel: function () { 13933 $(checkbox).prop("checked", !$(checkbox).prop("checked")); 13934 } 13935 }); 13936} 13937 13938function setRememberMeExpirationLimit(dropdown) { 13939 ajax_request('/policies/set_attribute?attribute=remember_me_expiration_limit&value=' + dropdown.value); 13940} 13941 13942function setRemoteCheckValidateResponse(checkbox) { 13943 $('#validate_by_' + checkbox.value).show(); 13944 13945 switch (checkbox.value) { 13946 case 'code': 13947 $('#validate_by_text').hide(); 13948 break; 13949 13950 case 'text': 13951 $('#validate_by_code').hide(); 13952 break; 13953 } 13954} 13955 13956function add_account_field_matching(available_account_fields) { 13957 let id = Math.floor(100000 + Math.random() * 900000); 13958 let html = '<p><select id="matching[account_field][' + id + ']" name="matching[account_field][' + id + ']">'; 13959 13960 $.each(available_account_fields, function(i, v) { 13961 html += '<option value="' + v.value + '">' + v.name + '</option>'; 13962 }); 13963 13964 html += '</select> <i class="arrowRight"></i> <input class="textInput" id="matching[attribute][' + id + ']" name="matching[attribute][' + id + ']" placeholder="Enter SAML attribute ..." type="text"> <i class="delete" onclick="remove_account_field_matching(this)"></i></p>'; 13965 13966 $('#account_field_matching').append(html); 13967} 13968 13969function remove_account_field_matching(element) { 13970 $(element).parent().remove(); 13971} 13972 13973function isBlank(string) { 13974 return string === null || string === undefined || string.trim() === ''; 13975} 13976 13977function deselect_roles(role_ids, checkbox, prefix = "", is_teacher = false, confirm_teacher_message = "") { 13978 if (checkbox.checked) { 13979 for (let role_id of role_ids) { 13980 var element_id = (prefix == "" ? 'role_' + role_id : prefix + '_role_' + role_id); 13981 $('#' + element_id).prop('checked', false); 13982 } 13983 } else { 13984 if (is_teacher) { 13985 var confirmation = confirm(confirm_teacher_message); 13986 13987 if (!confirmation) { 13988 // if the user cancels, prevent unchecking the checkbox 13989 checkbox.checked = true; 13990 } 13991 } 13992 } 13993} 13994 13995function initScrollToTop() { 13996 const handleScroll = () => { 13997 let scrollToTopBtn = document.getElementById("scrollToTopBtn"); 13998 if (!scrollToTopBtn) return; 13999 14000 if (document.documentElement.scrollTop > 300) { 14001 scrollToTopBtn.classList.add("show"); 14002 } else { 14003 scrollToTopBtn.classList.remove("show"); 14004 } 14005 }; 14006 14007 const handleClick = (e) => { 14008 e.preventDefault(); 14009 window.scrollTo({ 14010 top: 0, 14011 behavior: "smooth" 14012 }); 14013 }; 14014 14015 // Remove any existing scroll listeners to prevent duplicates 14016 window.removeEventListener("scroll", handleScroll); 14017 14018 // Add scroll listener after partial page update 14019 window.addEventListener("scroll", handleScroll); 14020 14021 document.addEventListener("click", (e) => { 14022 if (e.target.closest("#scrollToTopBtn")) { 14023 handleClick(e); 14024 } 14025 }); 14026} 14027 14028$(document).ready(function () { 14029 initScrollToTop(); 14030}); 14031 14032$(document).ready(function () { 14033 // Enable space key functionality for anchor tags with role="button" 14034 $(document).on('keydown', 'a[role="button"]', function(e) { 14035 if (e.key === ' ' || e.keyCode === 32) { 14036 e.preventDefault(); 14037 // Native click() so real DOM listeners fire too; suppress the default 14038 // for "#"/absent hrefs so Space doesn't scroll to top (jQuery's trigger() 14039 // does neither of these, see PR discussion). 14040 const href = this.getAttribute('href'); 14041 if (!href || href === '#') { 14042 const el = this; 14043 const suppressHashJump = function(ev) { ev.preventDefault(); }; 14044 el.addEventListener('click', suppressHashJump); 14045 try { 14046 el.click(); 14047 } finally { 14048 el.removeEventListener('click', suppressHashJump); 14049 } 14050 } else { 14051 this.click(); 14052 } 14053 } 14054 }); 14055}); 14056 14057// lti provider configurations 14058 14059function setProviderConfigurationEnabled(controller, providerConfigurationID, checkbox) { 14060 ajax_request('/' + controller + '/set_enabled/' + providerConfigurationID + '?value=' + check_s(checkbox)); 14061} 14062 14063function removeInput(element) { 14064 element.parentElement.remove(); 14065} 14066 14067function addInput(element, name) { 14068 element.parentElement.insertAdjacentHTML("afterend", "<p><label></label> <input class='textInput' type='text' name='" + name + "'> " + 14069 "<a onclick=\"removeInput(this)\"><i class=\"remove\"></i></a>\n" +
14070 "<a onclick=\"addInput(this, '" + name + "')\"><i class=\"add\"></i></a></p>"); 14071} 14072 14073// AICC 14074 14075function set_aicc_attribute(checkbox) { 14076 $.post('/admin_aicc/set_attribute?attribute=' + checkbox.name +'&value=' + check_s(checkbox), function(){ 14077 location.reload(); 14078 }); 14079} 14080 14081function set_klass_aicc_auto_create(element, class_id) { 14082 ajax_request('/class_configure/set_aicc_auto_create/' + class_id + '?value=' + element.value); 14083} 14084 14085// set default_enrollment_on_class_copy 14086 14087function set_default_enrollment_on_class_copy(checkbox) { 14088 $.post('/class_default_settings/set_default_enrollment_on_class_copy?attribute=' + checkbox.name +'&value=' + check_s(checkbox), function(){ 14089 location.reload(); 14090 }); 14091} 14092 14093function toggle_element_visibility(checkbox, selector, inverted) { 14094 if (inverted) { 14095 if (checkbox.checked) { 14096 $(selector).hide(); 14097 } else { 14098 $(selector).show(); 14099 } 14100 } else { 14101 if (checkbox.checked) { 14102 $(selector).show(); 14103 } else { 14104 $(selector).hide(); 14105 } 14106 } 14107} 14108 14109// panopto silent login 14110 14111function set_panopto_silent_login(checkbox) { 14112 $.post('/panopto_configure/set_panopto_silent_login?value=' + check_s(checkbox), function(){ 14113 location.reload(); 14114 }); 14115} 14116 14117function set_klass_panopto_silent_login(element, class_id) { 14118 ajax_request('/class_configure/set_panopto_silent_login/' + class_id + '?value=' + element.value); 14119} 14120 14121// batch submit for large forms 14122 14123function displayModalProgress(percentage, text) { 14124 let progressContainer = document.getElementById('progressBarContainer'); 14125 let overlay = document.getElementById('progressBarOverlay'); 14126 14127 if (!overlay) { 14128 document.body.insertAdjacentHTML('beforeend', ` 14129 <div id="progressBarOverlay"></div> 14130 `); 14131 overlay = document.getElementById('progressBarOverlay'); 14132 } 14133 14134 if (!progressContainer) { 14135 document.body.insertAdjacentHTML('beforeend', ` 14136 <div id="progressBarContainer"> 14137 <div id="progressText"></div> 14138 <div style="height: 20px; background: #f0f0f0; margin-top: 10px; border-radius: 5px; overflow: hidden;"> 14139 <div id="progressFill" style="height: 100%; width: 0; background: #4CAF50;"></div> 14140 </div> 14141 </div> 14142 `); 14143 progressContainer = document.getElementById('progressBarContainer'); 14144 } 14145 14146 document.getElementById('progressText').textContent = text; 14147 document.getElementById('progressFill').style.width = `${percentage}%`; 14148 14149 if (percentage >= 100) { 14150 setTimeout(() => { 14151 if (overlay) document.body.removeChild(overlay); 14152 if (progressContainer) document.body.removeChild(progressContainer); 14153 }, 1000); 14154 } 14155} 14156 14157function batchSubmit(form) { 14158 const formAction = form.getAttribute('action'); 14159 const rows = form.querySelectorAll('tr[data-batch]'); 14160 let maxBatch = 0; 14161 14162 rows.forEach(row => { 14163 const batchNumber = parseInt(row.getAttribute('data-batch'), 10); 14164 if (batchNumber > maxBatch) { 14165 maxBatch = batchNumber; 14166 } 14167 }); 14168 14169 const csrfToken = document.querySelector('meta[name="csrf-token"]')?.getAttribute('content'); 14170 const batchPromises = []; 14171 14172 for (let currentBatch = 0; currentBatch <= maxBatch; currentBatch++) { 14173 const batchPromise = new Promise((resolve, reject) => { 14174 const batchFormData = new FormData(); 14175 batchFormData.append('batch', currentBatch); 14176 batchFormData.append('total_batches', maxBatch); 14177 14178 form.querySelectorAll('.hidden input[type="hidden"]').forEach(input => { 14179 batchFormData.append(input.name, input.value); 14180 }); 14181 14182 form.querySelectorAll(`tr[data-batch="${currentBatch}"]`).forEach(row => { 14183 const inputs = row.querySelectorAll('input, select'); 14184 inputs.forEach(input => { 14185 if (input.name) { 14186 if (input.type !== 'hidden') { 14187 batchFormData.append(input.name, input.value); 14188 } else if (input.name.includes('_alt') || input.name.includes('(year)') || input.name.includes('(month)') || input.name.includes('(day)') || input.name.includes('(hours)') || input.name.includes('(minutes)')) { 14189 batchFormData.append(input.name, input.value); 14190 } 14191 } 14192 }); 14193 }); 14194 14195 fetch(formAction, { 14196 method: 'POST', 14197 body: batchFormData, 14198 headers: { 14199 'X-Requested-With': 'XMLHttpRequest', 14200 'X-CSRF-Token': csrfToken 14201 }, 14202 credentials: 'same-origin' 14203 }) 14204 .then(response => { 14205 if (!response.ok) { 14206 throw new Error(`Batch ${currentBatch} failed: ${response.statusText}`); 14207 } 14208 return response.text(); 14209 }) 14210 .then(data => { 14211 resolve(data); 14212 }) 14213 .catch(error => { 14214 console.error(error); 14215 reject(error); 14216 }); 14217 }); 14218 14219 batchPromises.push(batchPromise); 14220 } 14221 14222 displayModalProgress(0, `Submitting batch 1 of ${maxBatch + 1}...`); 14223 14224 let completedBatches = 0; 14225 14226 Promise.all(batchPromises.map((promise, index) => { 14227 return promise.then(result => { 14228 completedBatches++; 14229 const percentage = (completedBatches / (maxBatch + 1)) * 100; 14230 displayModalProgress(percentage, `Submitting batch ${completedBatches + 1} of ${maxBatch + 1}...`); 14231 return result; 14232 }); 14233 })) 14234 .then(results => { 14235 displayModalProgress(100, 'All batches sent successfully!'); 14236 setTimeout(() => { 14237 const fromParam = new URLSearchParams(window.location.search).get('from'); 14238 const info = results.map(result => { 14239 try { 14240 return JSON.parse(result).info; 14241 } catch (e) { 14242 return null; 14243 } 14244 }) 14245 .filter(infoItem => infoItem !== null && infoItem !== '') 14246 .join(', '); 14247 14248 if (fromParam) { 14249 if (info) { 14250 $(window).one('loadcomplete', function () { 14251 show_info(info); 14252 }); 14253 } 14254 Excalibur.Router.load(fromParam); 14255 } else { 14256 window.location.reload(); 14257 } 14258 }, 1000); 14259 }) 14260 .catch(error => { 14261 console.error("Batch submission failed:", error); 14262 show_error("Error submitting batches: " + error.message); 14263 }); 14264 14265 return false;
14266} 14267 14268function multi_select_popup(element) { 14269 const form = $(element).closest('form'); 14270 const selected_items = form.find("input[name*='select[]']:checked"); 14271 const select_all = form.find("input[onclick*='toggle_all']:checked"); 14272 let payload = {}; 14273 14274 if (selected_items.length > 0 || select_all.length > 0) { 14275 if (select_all.length > 0) { 14276 payload['select_all'] = true; 14277 } else { 14278 payload['select'] = [] 14279 14280 selected_items.each(function() { 14281 payload['select'].push($(this).val()); 14282 }); 14283 } 14284 14285 $.post($(element).attr('href'), payload, function(response) { 14286 $.facebox(response); 14287 }); 14288 } else { 14289 $.alert({content: no_items_selected}); 14290 } 14291 14292 return false; 14293} 14294 14295function secondary_organizations_selector(secOrgSelector, primOrgSelector, opts) { 14296 let secondaryOrganizationsElement = $(secOrgSelector); 14297 let primaryOrganizationsElement = primOrgSelector ? $(primOrgSelector) : null; 14298 14299 if (!secondaryOrganizationsElement.length) return; 14300 14301 function rebuild_secondary_options(primaryId) { 14302 const selectedIds = secondaryOrganizationsElement.val() || []; 14303 let selectedSet = {}; 14304 primaryId = primaryId ? String(primaryId) : ""; 14305 14306 selectedIds.forEach(function(id) { selectedSet[String(id)] = true; }); 14307 14308 if (secondaryOrganizationsElement.data("select2")) { 14309 secondaryOrganizationsElement.select2("destroy"); 14310 } 14311 14312 secondaryOrganizationsElement.empty(); 14313 14314 opts.forEach(function(org) { 14315 if (String(org[1]) === primaryId) { 14316 return; 14317 } 14318 14319 const option = new Option(org[0], org[1], false, !!selectedSet[String(org[1])]); 14320 secondaryOrganizationsElement.append(option); 14321 }); 14322 14323 secondaryOrganizationsElement.select2({ width: "100%" }); 14324 secondaryOrganizationsElement.val(selectedIds.filter(function(id) { return String(id) !== primaryId; })); 14325 secondaryOrganizationsElement.trigger("change"); 14326 } 14327 14328 if (secondaryOrganizationsElement.data("select2")) { 14329 secondaryOrganizationsElement.select2("destroy"); 14330 } 14331 secondaryOrganizationsElement.select2({ width: "100%" }); 14332 14333 primaryOrganizationsElement.on("change", function() { 14334 rebuild_secondary_options($(this).val()); 14335 }); 14336} 14337 14338// banner slide custom filter callback 14339 14340function bannerSlideFilterCallback(response) { 14341 const manager = window.conditionalFilterManager; 14342 const visiblePanel = $('div[class^=section_carousel_panel_].show'); 14343 const filterContainer = visiblePanel.find('.has_filter'); 14344 const saveUrl = manager.currentFilterOptions().save_url; 14345 14346 visiblePanel.find('.add_filter').hide(); 14347 filterContainer.find('.filter_conditions').text(response.name); 14348 filterContainer.show(); 14349 14350 // the slide renders an add and an edit trigger, each with its own registration, so both need the new id 14351 manager.filterIds().forEach(function (id) { 14352 const options = manager.filterOptions(id); 14353 14354 if (options.save_url && options.save_url === saveUrl) { 14355 options.filter_id = response.id; 14356 manager.setFilterOptions(id, options); 14357 } 14358 }); 14359}
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.