';
263 | }
264 | });
265 | $('#checkboxes').append(inputAppend);
266 | }
267 | function courseName(){
268 | var newName= [];
269 | newName = $.map($('input[id="course_name"]'), function(i){return i.value; });
270 | $.each(newName, function(index, item){
271 | if (item !==null){
272 | wholeName = item;
273 | }
274 | });
275 | }
276 | function updateName(){
277 | var url = "/api/v1/courses/" + parentId + "?course[name]=" + wholeName;
278 | $.ajax({
279 | 'cache' : false,
280 | 'url' : url ,
281 | 'type' : 'PUT',
282 | }).done(function() {
283 | closeDialog();
284 | });
285 | }
286 | /* This function gets the course code to update it. */
287 | function updatecourseCode(){
288 | var courseCode = '';
289 | var url = "/api/v1/courses/" + parentId;
290 | $.ajax({
291 | 'async': true,
292 | 'type': "GET",
293 | 'global': true,
294 | 'dataType': 'JSON',
295 | 'data': JSON.stringify(courseCode),
296 | 'contentType': "application/json",
297 | 'url': url,
298 | 'success': function data (i,o) {
299 |
300 | courseCode = i.course_code;
301 |
302 | var newcourseCode = courseCode.replace(/^[^A-Z]+/,'').replace(/\s\((.*)\)/g,'');
303 | console.log(newcourseCode);
304 | var url2 = "/api/v1/courses/" + parentId + "?course[course_code]=" + newcourseCode;
305 | $.ajax({
306 | 'cache' : false,
307 | 'url' : url2 ,
308 | 'type' : 'PUT',
309 | });
310 | },
311 | });
312 | }
313 | function openDialog() {
314 | try {
315 | createDialog();
316 | var wWidth = $(window).width();
317 | var dWidth = wWidth * 0.4;
318 | var wHeight = $(window).height();
319 | var dHeight = wHeight * 0.8;
320 | $('#cs_cross_dialog').dialog({
321 | 'title' : 'Crosslist Courses',
322 | 'autoOpen' : false,
323 | 'closeOnEscape': true,
324 | 'open': function () { $(".ui-dialog-titlebar-close").hide(); $(".ui-dialog").css("top", "10px");},
325 | 'buttons' : [ {
326 | 'text' : 'Cancel',
327 | 'click' : function() {
328 | $(this).dialog('destroy').remove();
329 | errors = [];
330 | updateMsgs();
331 | }
332 | },{
333 | 'text' : 'Submit',
334 | 'class': 'Button Button--primary',
335 | 'click' : submitButton
336 |
337 | } ],
338 | 'modal' : true,
339 | 'resizable' : false,
340 | 'height' : dHeight,
341 | 'width' : dWidth
342 | });
343 | if (!$('#cs_cross_dialog').dialog('isOpen')) {
344 | $('#cs_cross_dialog').dialog('open');
345 | }
346 | } catch (e) {
347 | console.log(e);
348 | }
349 | }
350 | function setChild() {
351 | array = $.map($('input[name="childCourses"]:checked'), function(c){return c.value; });
352 | }
353 | function processDialog() {
354 | $.each(array, function(index,item){
355 | var childCourse = item;
356 | var childSection;
357 | var url = "/api/v1/courses/" + childCourse + "/sections?";
358 | $.ajax({
359 | 'async': true,
360 | 'type': "GET",
361 | 'global': true,
362 | 'dataType': 'JSON',
363 | 'data': JSON.stringify(childSection),
364 | 'contentType': "application/json",
365 | 'url': url,
366 | 'success': function (data) {
367 | $.each(data, function(i,o){
368 | childSection = o.id;
369 | var url2 = "/api/v1/sections/" + childSection + "/crosslist/" + parentId +"?";
370 | $.ajax({
371 | 'cache' : false,
372 | 'url' : url2 ,
373 | 'type' : 'POST',
374 | }).done(function() {
375 | closeDialog();
376 | });
377 | });
378 | }
379 | });
380 | });
381 | }
382 | function setFavorite (){
383 | var url = "/api/v1/users/self/favorites/courses/" + parentId;
384 | $.ajax({
385 | 'cache' : false,
386 | 'url' : url ,
387 | 'type' : 'POST',
388 | });
389 | }
390 | function nonameDialog(){
391 | var el = document.querySelector('#nonamedialog');
392 | if (!el) {
393 | el = document.createElement('div');
394 | el.id = 'nonamedialog';
395 | var el2 = document.createElement('div');
396 | el.appendChild(el2);
397 | var el3 = document.createElement('p');
398 | el3.textContent = ' No course name entered!';
399 | el2.appendChild(el3);
400 | //direction 1
401 | var div1 = document.createElement('div');
402 | div1.classList.add('ic-image-text-combo');
403 | el.appendChild(div1);
404 | var icon;
405 | icon = document.createElement('i');
406 | icon.classList.add('icon-check');
407 | div1.appendChild(icon);
408 | var text = document.createElement('div');
409 | text.classList.add("text-success","ic-image-text-combo__text");
410 | text.textContent = 'Click "Crosslist Only" to continue without naming';
411 | div1.appendChild(text);
412 | //direction 2
413 | div1 = document.createElement('div');
414 | div1.classList.add('ic-image-text-combo');
415 | el.appendChild(div1);
416 | icon = document.createElement('i');
417 | icon.classList.add('icon-warning');
418 | div1.appendChild(icon);
419 | text = document.createElement('p');
420 | text.classList.add("text-warning","ic-image-text-combo__text");
421 | text.textContent = 'Click "Cancel" to go back and name your course.';
422 | div1.appendChild(text);
423 | var parent = document.querySelector('body');
424 | parent.appendChild(el);
425 | }
426 | }
427 | function opennonameDialog(){
428 | try {
429 | nonameDialog();
430 | $('#nonamedialog').dialog({
431 | 'title' : 'Crosslist Courses Only',
432 | 'autoOpen' : false,
433 | 'closeOnEscape': false,
434 | 'open': function () { $(".ui-dialog-titlebar-close").hide(); },
435 | 'buttons' : [{
436 | 'text' : 'Cancel',
437 | 'click' : function() {
438 | $(this).dialog('destroy').remove();
439 | errors = [];
440 | updateMsgs();
441 | }
442 | },{
443 | 'text' : 'Crosslist Only',
444 | 'class': 'Button Button--primary',
445 | 'click' : processDialog
446 | } ],
447 | 'modal' : true,
448 | 'resizable' : false,
449 | 'height' : 'auto',
450 | 'width' : '40%',
451 | });
452 | if (!$('#nonamedialog').dialog('isOpen')) {
453 | $('#nonamedialog').dialog('open');
454 | }
455 | } catch (e) {
456 | console.log(e);
457 | }
458 | }
459 | function nocrossDialog(){
460 | var el = document.querySelector('#nocrossdialog');
461 | if (!el) {
462 | el = document.createElement('div');
463 | el.id = 'nocrossdialog';
464 | var el2 = document.createElement('div');
465 | el.appendChild(el2);
466 | var el3 = document.createElement('p');
467 | el3.textContent = ' No courses selected to crosslist!';
468 | el2.appendChild(el3);
469 | //direction 1
470 | var div1 = document.createElement('div');
471 | div1.classList.add('ic-image-text-combo');
472 | el.appendChild(div1);
473 | var icon;
474 | icon = document.createElement('i');
475 | icon.classList.add('icon-check');
476 | div1.appendChild(icon);
477 | var text = document.createElement('div');
478 | text.classList.add("text-success","ic-image-text-combo__text");
479 | text.textContent = 'Click "Update Name" to continue without crosslisting';
480 | div1.appendChild(text);
481 | //direction 2
482 | div1 = document.createElement('div');
483 | div1.classList.add('ic-image-text-combo');
484 | el.appendChild(div1);
485 | icon = document.createElement('i');
486 | icon.classList.add('icon-warning');
487 | div1.appendChild(icon);
488 | text = document.createElement('p');
489 | text.classList.add("text-warning","ic-image-text-combo__text");
490 | text.textContent = 'Click "Cancel" to go back and choose courses to crosslist.';
491 | div1.appendChild(text);
492 | var parent = document.querySelector('body');
493 | parent.appendChild(el);
494 | }
495 | }
496 | function opennocrossDialog(){
497 | try {
498 | nocrossDialog();
499 | $('#nocrossdialog').dialog({
500 | 'title' : 'Update Course Name Only',
501 | 'autoOpen' : false,
502 | 'closeOnEscape': false,
503 | 'open': function () { $(".ui-dialog-titlebar-close").hide(); },
504 | 'buttons' : [ {
505 | 'text' : 'Cancel',
506 | 'click' : function() {
507 | $(this).dialog('destroy').remove();
508 | errors = [];
509 | updateMsgs();
510 | }
511 | },{
512 | 'text' : 'Update Name',
513 | 'class': 'Button Button--primary',
514 | 'click' : updateName
515 | } ],
516 | 'modal' : true,
517 | 'resizable' : false,
518 | 'height' : 'auto',
519 | 'width' : '40%'
520 | });
521 | if (!$('#nocrossdialog').dialog('isOpen')) {
522 | $('#nocrossdialog').dialog('open');
523 | }
524 | } catch (e) {
525 | console.log(e);
526 | }
527 | }
528 | function submitButton(){
529 | errors = [];
530 | courseName();
531 | setChild();
532 | if (wholeName !=='' || array !=+ ''){
533 | if (wholeName !=='' && array !=+ ''){
534 | updateName();
535 | updatecourseCode();
536 | setFavorite();
537 | processDialog();
538 | } else if (wholeName ==='' && array !=+ ''){
539 | updatecourseCode();
540 | setFavorite();
541 | opennonameDialog();
542 | }else{
543 | updatecourseCode();
544 | setFavorite();
545 | opennocrossDialog();
546 | }
547 | }else{
548 | errors.push('You must choose a course to crosslist or input a course name.');
549 | updateMsgs();
550 | }
551 | }
552 | function closeDialog(){
553 | $('#nocrossDialog').dialog('close');
554 | $('#nonameDialog').dialog('close');
555 | $('#cs_cross_dialog').dialog('close');
556 | $('#cs_cross_dialog2').dialog('close');
557 | window.location.reload(true);
558 | open_success_dialog();
559 | }
560 | function updateMsgs() {
561 | var msg = document.getElementById('cs_cross_msg');
562 | if (!msg) {
563 | return;
564 | }
565 | if (msg.hasChildNodes()) {
566 | msg.removeChild(msg.childNodes[0]);
567 | }
568 | if (typeof errors === 'undefined' || errors.length === 0) {
569 | msg.style.display = 'none';
570 | } else {
571 | var div1 = document.createElement('div');
572 | div1.classList.add('ic-flash-error');
573 | var div2;
574 | div2 = document.createElement('div');
575 | div2.classList.add('ic-flash__icon');
576 | div2.classList.add('aria-hidden="true"');
577 | div1.appendChild(div2);
578 | var icon;
579 | icon = document.createElement('i');
580 | icon.classList.add('icon-warning');
581 | div2.appendChild(icon);
582 | var ul = document.createElement('ul');
583 | for (var i = 0; i < errors.length; i++) {
584 | var li;
585 | li = document.createElement('li');
586 | li.textContent = errors[i];
587 | ul.appendChild(li);
588 | }
589 | div1.appendChild(ul);
590 | var button;
591 | button = document.createElement('button');
592 | button.type = 'button';
593 | button.classList.add("Button", "Button--icon-action", "close_link");
594 | div1.appendChild(button);
595 | icon = document.createElement('i');
596 | icon.classList.add('ic-icon-x');
597 | icon.classList.add('aria-hidden="true"');
598 | button.appendChild(icon);
599 | msg.appendChild(div1);
600 | msg.style.display = 'inline-block';
601 | }
602 | }
603 | function successDialog(){
604 | var el = document.querySelector('#success_dialog');
605 | if (!el) {
606 | el = document.createElement('div');
607 | el.id = 'success_dialog';
608 | var div1 = document.createElement('div');
609 | div1.classList.add('ic-flash-success');
610 | el.appendChild(div1);
611 | var div2 = document.createElement('div');
612 | div2.classList.add('ic-flash__icon');
613 | div2.classList.add('aria-hidden="true"');
614 | div1.appendChild(div2);
615 | var icon = document.createElement('i');
616 | icon.classList.add('icon-check');
617 | div2.appendChild(icon);
618 | var msg = document.createTextNode("The action completed successfully!");
619 | div1.appendChild(msg);
620 | var button = document.createElement('button');
621 | button.type = 'button';
622 | button.classList.add("Button", "Button--icon-action", "close_link");
623 | el.appendChild(button);
624 | icon = document.createElement('i');
625 | icon.classList.add('ic-icon-x');
626 | icon.classList.add('aria-hidden="true"');
627 | button.appendChild(icon);
628 | var parent = document.querySelector('body');
629 | parent.appendChild(el);
630 | }
631 | }
632 | function open_success_dialog(){
633 | try {
634 | successDialog();
635 | $('#success_dialog').dialog({
636 | 'autoOpen' : false,
637 | 'closeOnEscape': false,
638 | 'open': function () { $(".ui-dialog-titlebar").hide(); $(".ui-widget-content").css("background", "rgba(255, 255, 255, 0)"); $(".ui-dialog.ui-widget-content").css("box-shadow", "none");},
639 | 'modal' : true,
640 | 'resizable' : false,
641 | 'height' : 'auto',
642 | 'width' : '40%',
643 | });
644 | if (!$('#success_dialog').dialog('isOpen')) {
645 | $('#success_dialog').dialog('open');
646 | }
647 | } catch (e) {
648 | console.log(e);
649 | }
650 | }
651 | //Admin De-Crosslist
652 | function searchUser() {
653 | // Reset global variable errors
654 | errors = [];
655 | var userName;
656 | var el = document.getElementById('cs_cross_user');
657 | if (el.value && el.value.trim() !== '') {
658 | userName = el.value;
659 | var url = "/api/v1" + acc + "/users?search_term=" + userName + "&per_page=100";
660 | var userInfo;
661 | var x = document.getElementById("cs_cross_user");
662 | if (x.className === "ic-Input") {
663 | x.style.background = "url(https://imagizer.imageshack.us/a/img922/9776/IinEAt.gif) no-repeat right center";
664 | }
665 | $.ajax({
666 | 'async': true,
667 | 'type': "GET",
668 | 'global': true,
669 | 'dataType': 'JSON',
670 | 'data': JSON.stringify(userInfo),
671 | 'contentType': "application/json",
672 | 'url': url,
673 | 'success': function(data){
674 | if(data.length > 0){
675 | var toAppend = '';
676 | var blank = '';
677 | var select = document.getElementById('cs_cross_chooseuser');
678 | select.options.length = 0; // clear out existing items
679 | $.each(data,function(i,o){
680 | var n = o.name;
681 | if (n.toUpperCase() !== n){
682 | toAppend += '';
683 | }
684 | });
685 | blank += '';
686 | $('#cs_cross_chooseuser').append(blank);
687 | $('#cs_cross_chooseuser').append(toAppend);
688 | var x = document.getElementById("cs_cross_user");
689 | if (x.className === "ic-Input") {
690 | x.style.background = "#fff";
691 | }
692 | }else{
693 | errors.push('No user found');
694 | updateMsgs();
695 | }
696 | }
697 | });
698 | }else {
699 | errors.push('You must type in a name.');
700 | }
701 | updateMsgs();
702 | }
703 | function getCoursesAdmin(){
704 | // Reset global variable errors
705 | errors= [];
706 | user = document.getElementById('cs_cross_chooseuser').value;
707 | var url = "/api/v1/users/"+ user +"/courses?enrollment_state[]=active&per_page=100&include[]=term";
708 | $.ajax({
709 | 'async': true,
710 | 'type': "GET",
711 | 'global': true,
712 | 'dataType': 'JSON',
713 | 'data': JSON.stringify(courses),
714 | 'contentType': "application/json",
715 | 'url': url,
716 | 'success': function(courses){
717 | dedupThings = Array.from(courses.reduce((m, t) => m.set(t.id, t), new Map()).values());
718 | var toAppend = '';
719 | var blank ='';
720 | var select2 = document.getElementById('cs_cross_parentCourse');
721 | select2.options.length = 0; // clear out existing items
722 | termId = maxTerm(dedupThings);
723 | $.each(dedupThings, function(i, o){
724 | if (o.enrollment_term_id == termId && o.enrollments[0].type == "teacher") {
725 | toAppend += '';
726 | }
727 | });
728 | blank += '';
729 | $('#cs_cross_parentCourse').append(blank);
730 | $('#cs_cross_parentCourse').append(toAppend);
731 | }
732 | });
733 | }
734 | function setParentDecross(){
735 | // Reset global variable errors
736 | errors= [];
737 | user = document.getElementById('cs_cross_chooseuser').value;
738 | var url = "/api/v1/users/"+ user +"/courses?per_page=100&include[]=term&include[]=sections";
739 | $.ajax({
740 | 'async': true,
741 | 'type': "GET",
742 | 'global': true,
743 | 'dataType': 'JSON',
744 | 'data': JSON.stringify(courses),
745 | 'contentType': "application/json",
746 | 'url': url,
747 | 'success': function(courses){
748 | dedupThings = Array.from(courses.reduce((m, t) => m.set(t.id, t), new Map()).values());
749 | var toAppend = '';
750 | var blank ='';
751 | var select2 = document.getElementById('cs_cross_parentCourse');
752 | select2.options.length = 0; // clear out existing items
753 | termId = maxTerm(dedupThings);
754 | $.each(dedupThings, function(i, o){
755 | if (o.enrollment_term_id == termId && o.enrollments[0].type == "teacher" && o.sections.length > 1) {
756 | toAppend += '';
757 | }
758 | });
759 | blank += '';
760 | $('#cs_cross_parentCourse').append(blank);
761 | $('#cs_cross_parentCourse').append(toAppend);
762 | }
763 | });
764 | }
765 | function getSections(){
766 | var courseSections;
767 | parentId = document.getElementById("cs_cross_parentCourse").value;
768 | var url = "/api/v1/courses/" + parentId + "/sections?";
769 | $.ajax({
770 | 'async': true,
771 | 'type': "GET",
772 | 'global': true,
773 | 'dataType': 'JSON',
774 | 'data': JSON.stringify(courseSections),
775 | 'contentType': "application/json",
776 | 'url': url,
777 | 'success': function (courseSections) {
778 | $.each(courseSections, function(index,item){
779 | array = item.id;
780 | if(array !== parentId){
781 | var url2 = "/api/v1/sections/" + array + "/crosslist/";
782 | $.ajax({
783 | 'cache' : false,
784 | 'url' : url2 ,
785 | 'type' : 'DELETE',
786 |
787 | }).done(function() {
788 | closeDialog();
789 | });
790 | }
791 | });
792 | }
793 | });
794 | }
795 | function openDialog2() {
796 | try {
797 | createDialog2();
798 | var wWidth = $(window).width();
799 | var dWidth = wWidth * 0.4;
800 | var wHeight = $(window).height();
801 | var dHeight = wHeight * 0.8;
802 | $('#cs_cross_dialog2').dialog({
803 | 'title' : 'Admin De-Crosslist Tool',
804 | 'autoOpen' : false,
805 | 'closeOnEscape': true,
806 | 'open': function () { $(".ui-dialog-titlebar-close").hide(); $(".ui-dialog").css("top", "10px");},
807 | 'buttons' : [ {
808 | 'text' : 'Cancel',
809 | 'click' : function() {
810 | $(this).dialog('destroy').remove();
811 | errors = [];
812 | updateMsgs();
813 | }
814 | },{
815 | 'text' : 'Submit',
816 | 'class': 'Button Button--primary',
817 | 'click' : getSections
818 | } ],
819 | 'modal' : true,
820 | 'resizable' : false,
821 | 'height' : dHeight,
822 | 'width' : dWidth,
823 | });
824 | if (!$('#cs_cross_dialog2').dialog('isOpen')) {
825 | $('#cs_cross_dialog2').dialog('open');
826 | }
827 | } catch (e) {
828 | console.log(e);
829 | }
830 | }
831 | function createDialog2() {
832 | var el = document.querySelector('#cs_cross_dialog2');
833 | if (!el) {
834 | el = document.createElement('form');
835 | el.id = 'cs_cross_dialog2';
836 | el.classList.add("ic-Form-control","account_search_form");
837 | var label = document.createElement('label');
838 | label.htmlFor = 'cs_cross_user';
839 | label.textContent = 'Search For Teacher:';
840 | label.classList.add('ic-Label');
841 | el.appendChild(label);
842 | var el11 = document.createElement('div');
843 | el11.style =('margin: 0 0 10px 0');
844 | el11.classList.add('ic-Input-group');
845 | el.appendChild(el11);
846 | var input = document.createElement('input');
847 | input.classList.add('ic-Input');
848 | input.id = 'cs_cross_user';
849 | input.type = 'text';
850 | input.placeholder = 'Enter Teacher Name';
851 | el11.appendChild(input);
852 | $("#cs_cross_user").keyup(function(event){
853 | if(event.keyCode == 13){
854 | $("#btnSearch").click();
855 | }
856 | });
857 | var searchButton = document.createElement('button');
858 | searchButton.type = 'button';
859 | searchButton.id = 'btnSearch';
860 | searchButton.textContent = 'Search';
861 | searchButton.onclick = searchUser;
862 | searchButton.classList.add('Button');
863 | el11.appendChild(searchButton);
864 | //teacher dropdown
865 | label = document.createElement('label');
866 | label.htmlFor = 'cs_cross_choosuser';
867 | label.textContent = 'Search Results';
868 | label.classList.add('ic-Label');
869 | el.appendChild(label);
870 | var select = document.createElement('select');
871 | select.id = 'cs_cross_chooseuser';
872 | select.classList.add('ic-Input');
873 | select.placeholder = 'Select Teacher:';
874 | select.onchange = setParentDecross;
875 | el.appendChild(select);
876 | var el5 = document.createElement('div');
877 | el5.classList.add('ic-Form-control');
878 | el.appendChild(el5);
879 | var br = document.createElement('hr');
880 | el5.appendChild(br);
881 | label = document.createElement('label');
882 | label.htmlFor = 'cs_cross_parentCourse';
883 | label.textContent = 'Step 1: Select Bucket Course:';
884 | label.classList.add('ic-Label');
885 | el5.appendChild(label);
886 | select = document.createElement('select');
887 | select.id = 'cs_cross_parentCourse';
888 | select.classList.add('ic-Input');
889 | el5.appendChild(select);
890 | //message flash
891 | var msg = document.createElement('div');
892 | msg.id = 'cs_cross_msg2';
893 | //msg.classList.add('ic-flash-warning');
894 | msg.style.display = 'none';
895 | el.appendChild(msg);
896 | var parent = document.querySelector('body');
897 | parent.appendChild(el);
898 | }
899 | }
900 | function updateMsgs2() {
901 | var msg = document.getElementById('cs_cross_msg2');
902 | if (!msg) {
903 | return;
904 | }
905 | if (msg.hasChildNodes()) {
906 | msg.removeChild(msg.childNodes[0]);
907 | }
908 | if (typeof errors === 'undefined' || errors.length === 0) {
909 | msg.style.display = 'none';
910 | } else {
911 | var div1 = document.createElement('div');
912 | div1.classList.add('ic-flash-error');
913 | var div2;
914 | div2 = document.createElement('div');
915 | div2.classList.add('ic-flash__icon');
916 | div2.classList.add('aria-hidden="true"');
917 | div1.appendChild(div2);
918 | var icon;
919 | icon = document.createElement('i');
920 | icon.classList.add('icon-warning');
921 | div2.appendChild(icon);
922 | var ul = document.createElement('ul');
923 | for (var i = 0; i < errors.length; i++) {
924 | var li;
925 | li = document.createElement('li');
926 | li.textContent = errors[i];
927 | ul.appendChild(li);
928 | }
929 | div1.appendChild(ul);
930 | var button;
931 | button = document.createElement('button');
932 | button.type = 'button';
933 | button.classList.add("Button", "Button--icon-action", "close_link");
934 | div1.appendChild(button);
935 | icon = document.createElement('i');
936 | icon.classList.add('ic-icon-x');
937 | icon.classList.add('aria-hidden="true"');
938 | button.appendChild(icon);
939 | msg.appendChild(div1);
940 | msg.style.display = 'inline-block';
941 | }
942 | }
943 | //Admin Crosslist
944 | function add_buttonAdmin(){
945 |
946 | var rightDiv = document.querySelector('div#right-side-wrapper');
947 | rightDiv.style.display='inline';
948 | rightDiv.style.width='auto';
949 | var parent = document.querySelector('aside#right-side');
950 | if (parent) {
951 | var el = parent.querySelector('#cs_cross');
952 | if (!el) {
953 | el = document.createElement('button');
954 | el.classList.add('Button','Button--primary','Button--small','button-sidebar-wide','element_toggler');
955 | el.type = 'button';
956 | el.id = 'cs_cross';
957 | el.style.width = '175px';
958 | var icon = document.createElement('i');
959 | icon.classList.add('icon-sis-synced');
960 | el.appendChild(icon);
961 | var txt = document.createTextNode(' Admin Crosslist Tool');
962 | el.appendChild(txt);
963 | el.addEventListener('click', openDialog3);
964 | parent.appendChild(el);
965 | }
966 | //decrosslist button
967 | var el2 = parent.querySelector('#cs_decross');
968 | if (!el2) {
969 | el2 = document.createElement('button');
970 | el2.classList.add('Button','Button--secondary','Button--small','button-sidebar-wide','element_toggler');
971 | el2.type = 'button';
972 | el2.id = 'cs_decross';
973 | el2.style.width = '175px';
974 | var icon2 = document.createElement('i');
975 | icon2.classList.add('icon-sis-not-synced');
976 | el2.appendChild(icon2);
977 | var txt2 = document.createTextNode(' De-Crosslist Courses');
978 | el2.appendChild(txt2);
979 | el2.addEventListener('click', openDialog2);
980 | parent.appendChild(el2);
981 | }
982 | }
983 | }
984 | function adminDialog() {
985 | var el = document.querySelector('#cs_admin_dialog');
986 | if (!el) {
987 | //User Search
988 | el = document.createElement('form');
989 | el.id = 'cs_admin_dialog';
990 | el.classList.add("ic-Form-control","account_search_form");
991 | var label = document.createElement('label');
992 | label.htmlFor = 'cs_cross_user';
993 | label.textContent = 'Search For Teacher:';
994 | label.classList.add('ic-Label');
995 | el.appendChild(label);
996 | var el11 = document.createElement('div');
997 | el11.style =('margin: 0 0 10px 0');
998 | el11.classList.add('ic-Input-group');
999 | el.appendChild(el11);
1000 | var input = document.createElement('input');
1001 | input.classList.add('ic-Input');
1002 | input.id = 'cs_cross_user';
1003 | input.type = 'text';
1004 | input.placeholder = 'Enter Teacher Name';
1005 | el11.appendChild(input);
1006 | var searchButton = document.createElement('button');
1007 | searchButton.type = 'button';
1008 | searchButton.id = 'btnSearch';
1009 | searchButton.textContent = 'Search';
1010 | searchButton.onclick = searchUser;
1011 | searchButton.classList.add('Button');
1012 | el11.appendChild(searchButton);
1013 | $("#cs_cross_user").keyup(function(event){
1014 | if(event.keyCode == 13){
1015 | $("#btnSearch").click();
1016 | }
1017 | });
1018 | //teacher dropdown
1019 | label = document.createElement('label');
1020 | label.htmlFor = 'cs_cross_Results';
1021 | label.textContent = 'Search Results';
1022 | label.classList.add('ic-Label');
1023 | el.appendChild(label);
1024 | var select = document.createElement('select');
1025 | select.id = 'cs_cross_chooseuser';
1026 | select.classList.add('ic-Input');
1027 | select.placeholder = 'Select Teacher:';
1028 | select.onchange = getCoursesAdmin;
1029 | el.appendChild(select);
1030 | var el5 = document.createElement('div');
1031 | el5.classList.add('ic-Form-control');
1032 | el.appendChild(el5);
1033 | var br = document.createElement('hr');
1034 | el5.appendChild(br);
1035 | label = document.createElement('label');
1036 | label.htmlFor = 'cs_cross_parentCourse';
1037 | label.textContent = 'Step 1: Select Bucket Course:';
1038 | label.classList.add('ic-Label');
1039 | el5.appendChild(label);
1040 | select = document.createElement('select');
1041 | select.id = 'cs_cross_parentCourse';
1042 | select.classList.add('ic-Input');
1043 | select.onchange = getChildren;
1044 | el5.appendChild(select);
1045 | //childcourse checkboxes
1046 | var el6 = document.createElement('fieldset');
1047 | el6.id = 'child_list';
1048 | el6.style.visibility = 'none';
1049 | el6.classList.add("ic-Fieldset", "ic-Fieldset--radio-checkbox");
1050 | el.appendChild(el6);
1051 | var el7 = document.createElement('legend');
1052 | el7.classList.add('ic-Legend');
1053 | el7.textContent = 'Step 2: Choose Courses to Crosslist Into Bucket Course:';
1054 | el6.appendChild(el7);
1055 | var el8 = document.createElement('div');
1056 | el8.id = 'checkboxes';
1057 | el8.classList.add('ic-Checkbox-group');
1058 | el6.appendChild(el8);
1059 | //Course Name
1060 | var el9 = document.createElement('div');
1061 | el9.id = 'course_div';
1062 | el9.style.visibility = 'none';
1063 | el9.classList.add('ic-Form-control');
1064 | el.appendChild(el9);
1065 | label = document.createElement('label');
1066 | label.htmlFor = 'course_name';
1067 | label.textContent = 'Step 3: Course Name:';
1068 | label.classList.add('ic-Label');
1069 | el9.appendChild(label);
1070 | input = document.createElement('input');
1071 | input.id = 'course_name';
1072 | input.classList.add('ic-Input');
1073 | input.type = 'text';
1074 | input.placeholder = 'Campus Initials Course Name Teacher Name (First Initial.Last Name)';
1075 | el9.appendChild(input);
1076 | //Course Name Examples
1077 | var el10 = document.createElement('p');
1078 | el10.id = 'examples';
1079 | el10.style.visibility = 'none';
1080 | el10.classList = 'text-info';
1081 | el.appendChild(el10);
1082 | var ol = document.createElement('ol');
1083 | ol.textContent = 'Examples:';
1084 | ol.classList = 'unstyled';
1085 | el10.appendChild(ol);
1086 | var li = document.createElement('li');
1087 | li.textContent = 'KHS English III A M.Smith';
1088 | ol.appendChild(li);
1089 | li = document.createElement('li');
1090 | li.textContent = 'BJH 8 Science KAP G.Moreno';
1091 | ol.appendChild(li);
1092 | li = document.createElement('li');
1093 | li.textContent = 'KDE 5 Math G.Rorey';
1094 | ol.appendChild(li);
1095 | //message flash
1096 | var msg = document.createElement('div');
1097 | msg.id = 'cs_cross_msg';
1098 | //msg.classList.add('ic-flash-warning');
1099 | msg.style.display = 'none';
1100 | el.appendChild(msg);
1101 | var parent = document.querySelector('body');
1102 | parent.appendChild(el);
1103 | }
1104 | }
1105 | function openDialog3() {
1106 | try {
1107 | adminDialog();
1108 | var wWidth = $(window).width();
1109 | var dWidth = wWidth * 0.4;
1110 | var wHeight = $(window).height();
1111 | var dHeight = wHeight * 0.8;
1112 | $('#cs_admin_dialog').dialog({
1113 | 'title' : 'Admin Crosslist Tool',
1114 | 'autoOpen' : false,
1115 | 'closeOnEscape': true,
1116 | 'open': function () { $(".ui-dialog-titlebar-close").hide(); $(".ui-dialog").css("top", "10px");},
1117 | 'buttons' : [ {
1118 | 'text' : 'Cancel',
1119 | 'click' : function() {
1120 | $(this).dialog('destroy').remove();
1121 | errors = [];
1122 | updateMsgs();
1123 | }
1124 | },{
1125 | 'text' : 'Submit',
1126 | 'class': 'Button Button--primary',
1127 | 'click' : submitButton
1128 | } ],
1129 | 'modal' : true,
1130 | 'resizable' : false,
1131 | 'height' : dHeight,
1132 | 'width' : dWidth,
1133 | });
1134 | if (!$('#cs_admin_dialog').dialog('isOpen')) {
1135 | $('#cs_admin_dialog').dialog('open');
1136 | }
1137 | } catch (e) {
1138 | console.log(e);
1139 | }
1140 | }
1141 |
1142 |
1143 | })();
1144 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2017 Chad Scott
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # CanvasUserScripts
2 | No Longer Supported
3 | All - I've moved on and my current school does not use Canvas, so unfortunately, I will not be able to maintain these any longer.
4 |
5 |
6 | UserScripts for Canvas LMS
7 |
8 | Canvas Crosslisting.user.js is a very basic tool in which the user inputs the course number of the parent course and child course and then the two are crosslisted together.
9 |
10 | instructor and admin crosslisting tools.js is a more robust script in which the instructor's current term courses are loaded in a dropdown menu to choose the parent course. Then the remaining courses are dynamically created and are selectable to be child courses. Finally, the instructor can rename the parent course and submit to finalize the crosslisting and renaming actions. The instructor can also choose to crosslist without renaming and rename without crosslisting. On the subaccount page, it also adds the ability for root level admins to search for a user and then perform the same tasks as an instructor.
11 |
12 | Canvas Course Event Manager is a script that will allow a user to remove the dates or delete events from a course calendar. The user can select all events displayed (100 at a time) or select specific events.
13 |
14 | Canvas Remove Student Tool is a script that will allow an admin to remove students from courses in bulk. The table is sortable by name or last activity date. The "Add More" button will load the next 100 students. It is useful for managing manually created course enrollments for clubs, activities, and special courses.
15 |
16 | Print Canvas Quizzes is a script that will allow a user to print a quiz from the preview page.
17 |
18 |
Features
19 |
20 |
Adds a "Print Quiz" button below the question navigation pane.
21 |
Auto-page break: This will keep all question content on the same page and prevents a page break in the middle of a question.
22 |
The page is set to zoom to 74% to make it sized appropriately for printing.
23 |
Adjusts certain question types for legibility and space efficiency
24 |
Hides "This is a preview..." banner and "Submit Quiz" button
25 |
The print dialog will automatically pop-up for the user
26 |
27 |
Multiple Choice: Left aligns choices, all one column
28 |
Matching: Removes drop-down menu and creates a "answer bank" at the bottom of the question box
29 |
Multiple Dropdowns: Expands the dropdowns to width and height of content
30 |
31 |
32 |
Limitations
33 |
34 |
The quiz must be viewed from the "Preview Quiz" page
35 |
All questions must be visible on the page, which means the "Show one question at a time" must be unchecked
36 |
Currently, the zoom level of the page is not editable by the user, except through the printer dialog window
37 |
Not usable in the Quizzez.next LTI
38 |
39 |
40 |
41 | Remove Color Overlay is a script that removes the color overlay of courses with course images on the Dashboard. This is a workaround since admin is unable to set the default Dashboard experience for users.
42 |
--------------------------------------------------------------------------------
/instructor and admin crosslisting tools.user.js:
--------------------------------------------------------------------------------
1 | // ==UserScript==
2 | // @name KatyISD Instructor and Admin Crosslisting Tools
3 | // @namespace https://github.com/sukotsuchido/CanvasUserScripts
4 | // @version 2.1
5 | // @description A Canvas UserScript to facilitate crosslisting of courses.
6 | // @author Chad Scott (ChadScott@katyisd.org)
7 | // @include https://*.instructure.com/courses
8 | // @include https://*.instructure.com/accounts/*
9 | // @grant none
10 | // ==/UserScript==
11 | (function() {
12 | 'use strict';
13 | var assocRegex = new RegExp('^/courses$');
14 | var assocRegex2 = new RegExp('^/accounts/([0-9]+)$');
15 | var acc = window.location.pathname;
16 | var errors = [];
17 | var parentId = [];
18 | var maxValue = 1;
19 | var termId = '';
20 | var courses = {};
21 | var dedupThings = [];
22 | var wholeName = '';
23 | var array =[];
24 | var user = '';
25 | /* role setup: Change the roles you want to have access to the crosslisting features. assocRegex is for the button on the all courses page and assocRegex2 is for the admin page. */
26 | var roles = ENV.current_user_roles;
27 | var cxbuttonRoles = ["admin", "teacher", "root_admin"];
28 | var admincxbuttonRoles = ["root_admin"];
29 | var test1 = cxbuttonRoles.some(el => roles.includes(el));
30 | var test2 = admincxbuttonRoles.some(el => roles.includes(el));
31 | if( (test1 === true) && (assocRegex.test(window.location.pathname))){
32 | getCourses();
33 | }
34 | if( (test2 === true) && (assocRegex2.test(window.location.pathname))){
35 | add_buttonAdmin();
36 | }
37 |
38 | /* This adds the crosslist button to the all courses page and runs the function openDialog when clicked. */
39 | function add_button() {
40 | var parent = document.querySelector('div.ic-Action-header__Secondary');
41 | if (parent) {
42 | var el = parent.querySelector('#jj_cross');
43 | if (!el) {
44 | el = document.createElement('button');
45 | el.classList.add('Button','element_toggler');
46 | el.type = 'button';
47 | el.id = 'jj_cross';
48 | var icon = document.createElement('i');
49 | icon.classList.add('icon-sis-synced');
50 | el.appendChild(icon);
51 | var txt = document.createTextNode(' Crosslist Courses');
52 | el.appendChild(txt);
53 | el.addEventListener('click', openDialog);
54 | parent.appendChild(el);
55 | }
56 | }
57 | }
58 | /* This function creates the main popup window users interact with the crosslist their courses.
59 | I followed the Canvas Style Guide as much as possible to the CSS already available to create the form elements. */
60 | function createDialog() {
61 | var el = document.querySelector('#jj_cross_dialog');
62 | if (!el) {
63 | el = document.createElement('form');
64 | el.id = 'jj_cross_dialog';
65 | el.classList.add('ic-Form-group');
66 | //Parent Course selection
67 | var help = document.createElement('div');
68 | help.innerHTML = '
Directions: Complete for each step to crosslist and rename your courses. Click OPTIONS for more information about Crosslisting.
Options
';
69 | help.classList.add('ic-Label');
70 | el.appendChild(help);
71 | var el5 = document.createElement('div');
72 | el5.classList.add('ic-Form-control');
73 | el.appendChild(el5);
74 | var label = document.createElement('label');
75 | label.htmlFor = 'jj_cross_parentCourse';
76 | label.innerHTML = 'Step 1: Select Bucket Course (Hover over step for more help)';
77 | label.classList.add('ic-Label');
78 | el5.appendChild(label);
79 | var select = document.createElement('select');
80 | select.id = 'jj_cross_parentCourse';
81 | select.classList.add('ic-Input');
82 | select.onchange = getChildren;
83 | el5.appendChild(select);
84 | //childcourse checkboxes
85 | var el6 = document.createElement('fieldset');
86 | el6.id = 'child_list';
87 | el6.style.visibility = 'hidden';
88 | el6.classList.add("ic-Fieldset", "ic-Fieldset--radio-checkbox");
89 | el.appendChild(el6);
90 | var el7 = document.createElement('legend');
91 | el7.classList.add('ic-Legend');
92 | el7.innerHTML = 'Step 2: Choose Courses to Crosslist Into Bucket Course (Hover over step for more help)';
93 | el6.appendChild(el7);
94 | var el8 = document.createElement('div');
95 | el8.id = 'checkboxes';
96 | el8.classList.add('ic-Checkbox-group');
97 | el6.appendChild(el8);
98 | //Course Name
99 | var el9 = document.createElement('div');
100 | el9.id = 'course_div';
101 | el9.style.visibility = 'hidden';
102 | el9.classList.add('ic-Form-control');
103 | el.appendChild(el9);
104 | label = document.createElement('label');
105 | label.htmlFor = 'course_name';
106 | label.innerHTML = ' Step 3: Set Course Name (Hover over step for more help)';
107 | label.classList.add('ic-Label');
108 | el9.appendChild(label);
109 | var input = document.createElement('input');
110 | input.id = 'course_name';
111 | input.classList.add('ic-Input');
112 | input.type = 'text';
113 | //input.placeholder = 'Campus Initials Course Name Teacher Name (First Initial.Last Name)';
114 | el9.appendChild(input);
115 | //Course Name Examples
116 | var el10 = document.createElement('p');
117 | el10.id = 'examples';
118 | el10.style.visibility = 'hidden';
119 | el10.classList = 'text-info';
120 | el.appendChild(el10);
121 | var ol = document.createElement('ol');
122 | ol.textContent = 'Examples:';
123 | //ol.style.border = "thin solid #0000FF";
124 | ol.classList = 'unstyled';
125 | el10.appendChild(ol);
126 | var li = document.createElement('li');
127 | li.textContent = 'High School: KHS English 3 A M.Smith';
128 | ol.appendChild(li);
129 | li = document.createElement('li');
130 | li.textContent = 'Junior High: BJH Spanish 1 PreAP G.Moreno';
131 | ol.appendChild(li);
132 | li = document.createElement('li');
133 | li.textContent = 'Elementary: KDE 4 Math G.Rorey';
134 | ol.appendChild(li);
135 | //message flash
136 | var msg = document.createElement('div');
137 | msg.id = 'jj_cross_msg';
138 | //msg.classList.add('ic-flash-warning');
139 | msg.style.display = 'none';
140 | el.appendChild(msg);
141 | var parent = document.querySelector('body');
142 | parent.appendChild(el);
143 | }
144 | setParent();
145 | /* opens the help dialog window */
146 | document.getElementById("action_helper").addEventListener("click", function(){
147 | openHelp();
148 | });
149 | }
150 |
151 | /* Help dialog window, explains the steps of how to crosslist */
152 | function createhelpDialog(){
153 | var el = document.querySelector('#help_dialog');
154 | if (!el) {
155 | el = document.createElement('div');
156 | el.innerHTML= '
Crosslist and Name Course: Complete all 3 steps Crosslist and Don\'t Rename Course: Complete steps 1 and 2 Only Rename Course: Complete steps 1 and 3
Hover over each step for more help.
';
157 | el.id = 'help_dialog';
158 | //Parent Course selection
159 | //message flash
160 | var msg = document.createElement('div');
161 | msg.id = 'jj_cross_msg';
162 | //msg.classList.add('ic-flash-warning');
163 | msg.style.display = 'none';
164 | el.appendChild(msg);
165 | var parent = document.querySelector('body');
166 | parent.appendChild(el);
167 | }
168 | }
169 |
170 | /* This function creates the modal window for the help dialog, I have hidden the titlebar close button and disabled the ability to esc close also. */
171 | function openHelp() {
172 | try {
173 | createhelpDialog();
174 | $('#help_dialog').dialog({
175 | 'title' : 'Possible Actions',
176 | 'autoOpen' : false,
177 | 'closeOnEscape': false,
178 | 'open': function () { $(".ui-dialog-titlebar-close").hide(); $(".ui-dialog").css("top", "10px");},
179 | 'buttons' : [ {
180 | 'text' : 'Close',
181 | 'click' : function() {
182 | $(this).dialog('destroy').remove();
183 | }
184 | } ],
185 | 'modal' : true,
186 | 'resizable' : false,
187 | 'height' : 'auto',
188 | 'width' : '30%'
189 | });
190 | if (!$('#help_dialog').dialog('isOpen')) {
191 | $('#help_dialog').dialog('open');
192 | }
193 | } catch (e) {
194 | console.log(e);
195 | }
196 | }
197 |
198 | /* This function sends an api request to get the current users course list. */
199 | function getCourses(){
200 | // Reset global variable errors
201 | errors= [];
202 | var url = "/api/v1/users/self/courses?inlcude[]=term&include[]=sections&per_page=100";
203 | $.ajax({
204 | 'async': true,
205 | 'type': "GET",
206 | 'global': true,
207 | 'dataType': 'JSON',
208 | 'data': JSON.stringify(courses),
209 | 'contentType': "application/json",
210 | 'url': url,
211 | 'success': function(courses){
212 | dedupThings = Array.from(courses.reduce((m, t) => m.set(t.id, t), new Map()).values());
213 | add_button();
214 | }
215 | });
216 | }
217 | /* This function sorts and returns only the most recent term id number. This prevents users from crosslisting into manually created courses. */
218 | function maxTerm(dedupThings){
219 | for(var i=0;i maxValue){
221 | maxValue = Number(dedupThings[i].enrollment_term_id);
222 | }
223 | }
224 | return maxValue;
225 | }
226 |
227 | /* This function takes the return from getTerm and then filters the courses for only that term id and sets the courses in the dropdown. */
228 | function setParent(){
229 | var toAppend = '';
230 | var select = document.getElementById('jj_cross_parentCourse');
231 | select.options.length = 0; // clear out existing items
232 | termId = maxTerm(dedupThings);
233 | $.each(dedupThings, function(i, o){
234 | if (o.enrollment_term_id == termId && o.enrollments[0].type == "teacher") {
235 | toAppend += '';
236 | }
237 | });
238 | var blank ='';
239 | blank += '';
240 | $('#jj_cross_parentCourse').append(blank);
241 | $('#jj_cross_parentCourse').append(toAppend);
242 | }
243 |
244 | /* This function reveals the rest of the form after the parent course is selected. It adds the remaining courses not chosen to be the
245 | parent course as check boxes.*/
246 | function getChildren(){
247 | var show = document.getElementById('child_list');
248 | show.style.visibility = 'visible';
249 | var show2 = document.getElementById('course_div');
250 | show2.style.visibility = 'visible';
251 | var show3 = document.getElementById('examples');
252 | show3.style.visibility = 'visible';
253 | var clear = document.getElementById('checkboxes');
254 | var clear3='';
255 | if (clear.innerHTML !== null){
256 | clear.innerHTML = "";
257 | }
258 | parentId = document.getElementById("jj_cross_parentCourse").value;
259 | var labelAppend = '';
260 | var inputAppend = '';
261 | $.each(dedupThings,function(i,o){
262 | if (o.enrollment_term_id == termId && o.enrollments[0].type == "teacher" && o.id != parentId) {
263 | labelAppend += ''+'';
264 | clear3=labelAppend;
265 | if (labelAppend !== null){
266 | labelAppend = '';
267 | }
268 | inputAppend += '