[ Index ] |
PHP Cross Reference of moodle-2.8 |
[Summary view] [Print] [Text view]
1 YUI.add('moodle-course-management', function (Y, NAME) { 2 3 /** 4 * Provides drop down menus for list of action links. 5 * 6 * @module moodle-course-management 7 */ 8 9 /** 10 * Management JS console. 11 * 12 * Provides the organisation for course and category management JS. 13 * 14 * @namespace M.course.management 15 * @class Console 16 * @constructor 17 * @extends Base 18 */ 19 function Console() { 20 Console.superclass.constructor.apply(this, arguments); 21 } 22 Console.NAME = 'moodle-course-management'; 23 Console.CSS_PREFIX = 'management'; 24 Console.ATTRS = { 25 /** 26 * The HTML element containing the management interface. 27 * @attribute element 28 * @type Node 29 */ 30 element : { 31 setter : function(node) { 32 if (typeof node === 'string') { 33 node = Y.one('#'+node); 34 } 35 return node; 36 } 37 }, 38 39 /** 40 * The category listing container node. 41 * @attribute categorylisting 42 * @type Node 43 * @default null 44 */ 45 categorylisting : { 46 value : null 47 }, 48 49 /** 50 * The course listing container node. 51 * @attribute courselisting 52 * @type Node 53 * @default null 54 */ 55 courselisting : { 56 value : null 57 }, 58 59 /** 60 * The course details container node. 61 * @attribute coursedetails 62 * @type Node|null 63 * @default null 64 */ 65 coursedetails : { 66 value : null 67 }, 68 69 /** 70 * The id of the currently active category. 71 * @attribute activecategoryid 72 * @type Number 73 * @default null 74 */ 75 activecategoryid : { 76 value : null 77 }, 78 79 /** 80 * The id of the currently active course. 81 * @attribute activecourseid 82 * @type Number 83 * @default Null 84 */ 85 activecourseid : { 86 value : null 87 }, 88 89 /** 90 * The categories that are currently available through the management interface. 91 * @attribute categories 92 * @type Array 93 * @default [] 94 */ 95 categories : { 96 setter : function(item, name) { 97 if (Y.Lang.isArray(item)) { 98 return item; 99 } 100 var items = this.get(name); 101 items.push(item); 102 return items; 103 }, 104 value : [] 105 }, 106 107 /** 108 * The courses that are currently available through the management interface. 109 * @attribute courses 110 * @type Course[] 111 * @default Array 112 */ 113 courses : { 114 validator : function(val) { 115 return Y.Lang.isArray(val); 116 }, 117 value : [] 118 }, 119 120 /** 121 * The currently displayed page of courses. 122 * @attribute page 123 * @type Number 124 * @default null 125 */ 126 page : { 127 getter : function(value, name) { 128 if (value === null) { 129 value = this.get('element').getData(name); 130 this.set(name, value); 131 } 132 return value; 133 }, 134 value : null 135 }, 136 137 /** 138 * The total pages of courses that can be shown for this category. 139 * @attribute totalpages 140 * @type Number 141 * @default null 142 */ 143 totalpages : { 144 getter : function(value, name) { 145 if (value === null) { 146 value = this.get('element').getData(name); 147 this.set(name, value); 148 } 149 return value; 150 }, 151 value : null 152 }, 153 154 /** 155 * The total number of courses belonging to this category. 156 * @attribute totalcourses 157 * @type Number 158 * @default null 159 */ 160 totalcourses : { 161 getter : function(value, name) { 162 if (value === null) { 163 value = this.get('element').getData(name); 164 this.set(name, value); 165 } 166 return value; 167 }, 168 value : null 169 }, 170 171 /** 172 * The URL to use for AJAX actions/requests. 173 * @attribute ajaxurl 174 * @type String 175 * @default /course/ajax/management.php 176 */ 177 ajaxurl : { 178 getter : function(value) { 179 if (value === null) { 180 value = M.cfg.wwwroot + '/course/ajax/management.php'; 181 } 182 return value; 183 }, 184 value : null 185 }, 186 187 /** 188 * The drag drop handler 189 * @attribute dragdrop 190 * @type DragDrop 191 * @default null 192 */ 193 dragdrop : { 194 value : null 195 } 196 }; 197 Console.prototype = { 198 199 /** 200 * Gets set to true once the first categories have been initialised. 201 * @property categoriesinit 202 * @private 203 * @type {boolean} 204 */ 205 categoriesinit : false, 206 207 /** 208 * Initialises a new instance of the Console. 209 * @method initializer 210 */ 211 initializer : function() { 212 this.set('element', 'coursecat-management'); 213 var element = this.get('element'), 214 categorylisting = element.one('#category-listing'), 215 courselisting = element.one('#course-listing'), 216 selectedcategory = null, 217 selectedcourse = null; 218 219 if (categorylisting) { 220 selectedcategory = categorylisting.one('.listitem[data-selected="1"]'); 221 } 222 if (courselisting) { 223 selectedcourse = courselisting.one('.listitem[data-selected="1"]'); 224 } 225 this.set('categorylisting', categorylisting); 226 this.set('courselisting', courselisting); 227 this.set('coursedetails', element.one('#course-detail')); 228 if (selectedcategory) { 229 this.set('activecategoryid', selectedcategory.getData('id')); 230 } 231 if (selectedcourse) { 232 this.set('activecourseid', selectedcourse.getData('id')); 233 } 234 this.initialiseCategories(categorylisting); 235 this.initialiseCourses(); 236 237 if (courselisting) { 238 // No need for dragdrop if we don't have a course listing. 239 this.set('dragdrop', new DragDrop({console:this})); 240 } 241 }, 242 243 /** 244 * Initialises all the categories being shown. 245 * @method initialiseCategories 246 * @private 247 * @return {boolean} 248 */ 249 initialiseCategories : function(listing) { 250 var count = 0; 251 if (!listing) { 252 return false; 253 } 254 255 // Disable category bulk actions as nothing will be selected on initialise. 256 var menumovecatto = listing.one('#menumovecategoriesto'); 257 if (menumovecatto) { 258 menumovecatto.setAttribute('disabled', true); 259 } 260 var menuresortcategoriesby = listing.one('#menuresortcategoriesby'); 261 if (menuresortcategoriesby) { 262 menuresortcategoriesby.setAttribute('disabled', true); 263 } 264 var menuresortcoursesby = listing.one('#menuresortcoursesby'); 265 if (menuresortcoursesby) { 266 menuresortcoursesby.setAttribute('disabled', true); 267 } 268 269 listing.all('.listitem[data-id]').each(function(node){ 270 this.set('categories', new Category({ 271 node : node, 272 console : this 273 })); 274 count++; 275 }, this); 276 if (!this.categoriesinit) { 277 this.get('categorylisting').delegate('click', this.handleCategoryDelegation, 'a[data-action]', this); 278 this.get('categorylisting').delegate('click', this.handleCategoryDelegation, 'input[name="bcat[]"]', this); 279 this.get('categorylisting').delegate('click', this.handleBulkSortByaction, '#menuselectsortby', this); 280 this.categoriesinit = true; 281 } else { 282 } 283 }, 284 285 /** 286 * Initialises all the categories being shown. 287 * @method initialiseCourses 288 * @private 289 * @return {boolean} 290 */ 291 initialiseCourses : function() { 292 var category = this.getCategoryById(this.get('activecategoryid')), 293 listing = this.get('courselisting'), 294 count = 0; 295 if (!listing) { 296 return false; 297 } 298 299 // Disable course move to bulk action as nothing will be selected on initialise. 300 var menumovecoursesto = listing.one('#menumovecoursesto'); 301 if (menumovecoursesto) { 302 menumovecoursesto.setAttribute('disabled', true); 303 } 304 305 listing.all('.listitem[data-id]').each(function(node){ 306 this.registerCourse(new Course({ 307 node : node, 308 console : this, 309 category : category 310 })); 311 count++; 312 }, this); 313 listing.delegate('click', this.handleCourseDelegation, 'a[data-action]', this); 314 listing.delegate('click', this.handleCourseDelegation, 'input[name="bc[]"]', this); 315 }, 316 317 /** 318 * Registers a course within the management display. 319 * @method registerCourse 320 * @param {Course} course 321 */ 322 registerCourse : function(course) { 323 var courses = this.get('courses'); 324 courses.push(course); 325 this.set('courses', courses); 326 }, 327 328 /** 329 * Handles the event fired by a delegated course listener. 330 * 331 * @method handleCourseDelegation 332 * @protected 333 * @param {EventFacade} e 334 */ 335 handleCourseDelegation : function(e) { 336 var target = e.currentTarget, 337 action = target.getData('action'), 338 courseid = target.ancestor('.listitem').getData('id'), 339 course = this.getCourseById(courseid); 340 if (course) { 341 course.handle(action, e); 342 } else { 343 } 344 }, 345 346 /** 347 * Handles the event fired by a delegated course listener. 348 * 349 * @method handleCategoryDelegation 350 * @protected 351 * @param {EventFacade} e 352 */ 353 handleCategoryDelegation : function(e) { 354 var target = e.currentTarget, 355 action = target.getData('action'), 356 categoryid = target.ancestor('.listitem').getData('id'), 357 category = this.getCategoryById(categoryid); 358 if (category) { 359 category.handle(action, e); 360 } else { 361 } 362 }, 363 364 /** 365 * Check if any course is selected. 366 * 367 * @method isCourseSelected 368 * @param {Node} checkboxnode Checkbox node on which action happened. 369 * @return bool 370 */ 371 isCourseSelected : function(checkboxnode) { 372 var selected = false; 373 374 // If any course selected then show move to category select box. 375 if (checkboxnode && checkboxnode.get('checked')) { 376 selected = true; 377 } else { 378 var i, 379 course, 380 courses = this.get('courses'), 381 length = courses.length; 382 for (i = 0; i < length; i++) { 383 if (courses.hasOwnProperty(i)) { 384 course = courses[i]; 385 if (course.get('node').one('input[name="bc[]"]').get('checked')) { 386 selected = true; 387 break; 388 } 389 } 390 } 391 } 392 return selected; 393 }, 394 395 /** 396 * Check if any category is selected. 397 * 398 * @method isCategorySelected 399 * @param {Node} checkboxnode Checkbox node on which action happened. 400 * @return bool 401 */ 402 isCategorySelected : function(checkboxnode) { 403 var selected = false; 404 405 // If any category selected then show move to category select box. 406 if (checkboxnode && checkboxnode.get('checked')) { 407 selected = true; 408 } else { 409 var i, 410 category, 411 categories = this.get('categories'), 412 length = categories.length; 413 for (i = 0; i < length; i++) { 414 if (categories.hasOwnProperty(i)) { 415 category = categories[i]; 416 if (category.get('node').one('input[name="bcat[]"]').get('checked')) { 417 selected = true; 418 break; 419 } 420 } 421 } 422 } 423 return selected; 424 }, 425 426 /** 427 * Handle bulk sort action. 428 * 429 * @method handleBulkSortByaction 430 * @protected 431 * @param {EventFacade} e 432 */ 433 handleBulkSortByaction : function(e) { 434 var sortcategoryby = this.get('categorylisting').one('#menuresortcategoriesby'), 435 sortcourseby = this.get('categorylisting').one('#menuresortcoursesby'), 436 sortbybutton = this.get('categorylisting').one('input[name="bulksort"]'); 437 sortby = e; 438 439 if (!sortby) { 440 sortby = this.get('categorylisting').one('#menuselectsortby'); 441 } else { 442 if (e && e.currentTarget) { 443 sortby = e.currentTarget; 444 } 445 } 446 447 // If no sortby select found then return as we can't do anything. 448 if (!sortby) { 449 return; 450 } 451 452 if ((this.get('categories').length <= 1) || (!this.isCategorySelected() && 453 (sortby.get("options").item(sortby.get('selectedIndex')).getAttribute('value') === 'selectedcategories'))) { 454 if (sortcategoryby) { 455 sortcategoryby.setAttribute('disabled', true); 456 } 457 if (sortcourseby) { 458 sortcourseby.setAttribute('disabled', true); 459 } 460 if (sortbybutton) { 461 sortbybutton.setAttribute('disabled', true); 462 } 463 } else { 464 if (sortcategoryby) { 465 sortcategoryby.removeAttribute('disabled'); 466 } 467 if (sortcourseby) { 468 sortcourseby.removeAttribute('disabled'); 469 } 470 if (sortbybutton) { 471 sortbybutton.removeAttribute('disabled'); 472 } 473 } 474 }, 475 476 /** 477 * Returns the category with the given ID. 478 * @method getCategoryById 479 * @param {Number} id 480 * @return {Category|Boolean} The category or false if it can't be found. 481 */ 482 getCategoryById : function(id) { 483 var i, 484 category, 485 categories = this.get('categories'), 486 length = categories.length; 487 for (i = 0; i < length; i++) { 488 if (categories.hasOwnProperty(i)) { 489 category = categories[i]; 490 if (category.get('categoryid') === id) { 491 return category; 492 } 493 } 494 } 495 return false; 496 }, 497 498 /** 499 * Returns the course with the given id. 500 * @method getCourseById 501 * @param {Number} id 502 * @return {Course|Boolean} The course or false if not found/ 503 */ 504 getCourseById : function(id) { 505 var i, 506 course, 507 courses = this.get('courses'), 508 length = courses.length; 509 for (i = 0; i < length; i++) { 510 if (courses.hasOwnProperty(i)) { 511 course = courses[i]; 512 if (course.get('courseid') === id) { 513 return course; 514 } 515 } 516 } 517 return false; 518 }, 519 520 /** 521 * Removes the course with the given ID. 522 * @method removeCourseById 523 * @param {Number} id 524 */ 525 removeCourseById : function(id) { 526 var courses = this.get('courses'), 527 length = courses.length, 528 course, 529 i; 530 for (i = 0; i < length; i++) { 531 course = courses[i]; 532 if (course.get('courseid') === id) { 533 courses.splice(i, 1); 534 break; 535 } 536 } 537 }, 538 539 /** 540 * Performs an AJAX action. 541 * 542 * @method performAjaxAction 543 * @param {String} action The action to perform. 544 * @param {Object} args The arguments to pass through with teh request. 545 * @param {Function} callback The function to call when all is done. 546 * @param {Object} context The object to use as the context for the callback. 547 */ 548 performAjaxAction : function(action, args, callback, context) { 549 var io = new Y.IO(); 550 args.action = action; 551 args.ajax = '1'; 552 args.sesskey = M.cfg.sesskey; 553 if (callback === null) { 554 callback = function() { 555 }; 556 } 557 io.send(this.get('ajaxurl'), { 558 method : 'POST', 559 on : { 560 complete : callback 561 }, 562 context : context, 563 data : build_querystring(args), 564 'arguments' : args 565 }); 566 } 567 }; 568 Y.extend(Console, Y.Base, Console.prototype); 569 570 M.course = M.course || {}; 571 M.course.management = M.course.management || {}; 572 M.course.management.console = null; 573 574 /** 575 * Initalises the course management console. 576 * 577 * @method M.course.management.init 578 * @static 579 * @param {Object} config 580 */ 581 M.course.management.init = function(config) { 582 M.course.management.console = new Console(config); 583 }; 584 /** 585 * Drag and Drop handler 586 * 587 * @namespace M.course.management 588 * @class DragDrop 589 * @constructor 590 * @extends Base 591 */ 592 function DragDrop(config) { 593 Console.superclass.constructor.apply(this, [config]); 594 } 595 DragDrop.NAME = 'moodle-course-management-dd'; 596 DragDrop.CSS_PREFIX = 'management-dd'; 597 DragDrop.ATTRS = { 598 /** 599 * The management console this drag and drop has been set up for. 600 * @attribute console 601 * @type Console 602 * @writeOnce 603 */ 604 console : { 605 writeOnce : 'initOnly' 606 } 607 }; 608 DragDrop.prototype = { 609 /** 610 * True if the user is dragging a course upwards. 611 * @property goingup 612 * @protected 613 * @default false 614 */ 615 goingup : false, 616 617 /** 618 * The last Y position of the course being dragged 619 * @property lasty 620 * @protected 621 * @default null 622 */ 623 lasty : null, 624 625 /** 626 * The sibling above the course being dragged currently (tracking its original position). 627 * 628 * @property previoussibling 629 * @protected 630 * @default false 631 */ 632 previoussibling : null, 633 634 /** 635 * Initialises the DragDrop instance. 636 * @method initializer 637 */ 638 initializer : function() { 639 var managementconsole = this.get('console'), 640 container = managementconsole.get('element'), 641 categorylisting = container.one('#category-listing'), 642 courselisting = container.one('#course-listing > .course-listing'), 643 categoryul = (categorylisting) ? categorylisting.one('ul.ml') : null, 644 courseul = (courselisting) ? courselisting.one('ul.ml') : null, 645 canmoveoutof = (courselisting) ? courselisting.getData('canmoveoutof') : false, 646 contstraint = (canmoveoutof) ? container : courseul; 647 648 if (!courseul) { 649 // No course listings found. 650 return false; 651 } 652 653 courseul.all('> li').each(function(li){ 654 this.initCourseListing(li, contstraint); 655 }, this); 656 courseul.setData('dd', new Y.DD.Drop({ 657 node: courseul 658 })); 659 if (canmoveoutof && categoryul) { 660 // Category UL may not be there if viewmode is just courses. 661 categoryul.all('li > div').each(function(div){ 662 this.initCategoryListitem(div); 663 }, this); 664 } 665 Y.DD.DDM.on('drag:start', this.dragStart, this); 666 Y.DD.DDM.on('drag:end', this.dragEnd, this); 667 Y.DD.DDM.on('drag:drag', this.dragDrag, this); 668 Y.DD.DDM.on('drop:over', this.dropOver, this); 669 Y.DD.DDM.on('drop:enter', this.dropEnter, this); 670 Y.DD.DDM.on('drop:exit', this.dropExit, this); 671 Y.DD.DDM.on('drop:hit', this.dropHit, this); 672 673 }, 674 675 /** 676 * Initialises a course listing. 677 * @method initCourseListing 678 * @param Node 679 */ 680 initCourseListing : function(node, contstraint) { 681 node.setData('dd', new Y.DD.Drag({ 682 node : node, 683 target : { 684 padding: '0 0 0 20' 685 } 686 }).addHandle( 687 '.drag-handle' 688 ).plug(Y.Plugin.DDProxy, { 689 moveOnEnd: false, 690 borderStyle: false 691 }).plug(Y.Plugin.DDConstrained, { 692 constrain2node: contstraint 693 })); 694 }, 695 696 /** 697 * Initialises a category listing. 698 * @method initCategoryListitem 699 * @param Node 700 */ 701 initCategoryListitem : function(node) { 702 node.setData('dd', new Y.DD.Drop({ 703 node: node 704 })); 705 }, 706 707 /** 708 * Dragging has started. 709 * @method dragStart 710 * @private 711 * @param {EventFacade} e 712 */ 713 dragStart : function(e) { 714 var drag = e.target, 715 node = drag.get('node'), 716 dragnode = drag.get('dragNode'); 717 node.addClass('course-being-dragged'); 718 dragnode.addClass('course-being-dragged-proxy').set('innerHTML', node.one('a.coursename').get('innerHTML')); 719 this.previoussibling = node.get('previousSibling'); 720 }, 721 722 /** 723 * Dragging has ended. 724 * @method dragEnd 725 * @private 726 * @param {EventFacade} e 727 */ 728 dragEnd : function(e) { 729 var drag = e.target, 730 node = drag.get('node'); 731 node.removeClass('course-being-dragged'); 732 this.get('console').get('element').all('#category-listing li.highlight').removeClass('highlight'); 733 }, 734 735 /** 736 * Dragging in progress. 737 * @method dragDrag 738 * @private 739 * @param {EventFacade} e 740 */ 741 dragDrag : function(e) { 742 var y = e.target.lastXY[1]; 743 if (y < this.lasty) { 744 this.goingup = true; 745 } else { 746 this.goingup = false; 747 } 748 this.lasty = y; 749 }, 750 751 /** 752 * The course has been dragged over a drop target. 753 * @method dropOver 754 * @private 755 * @param {EventFacade} e 756 */ 757 dropOver : function(e) { 758 //Get a reference to our drag and drop nodes 759 var drag = e.drag.get('node'), 760 drop = e.drop.get('node'), 761 tag = drop.get('tagName').toLowerCase(); 762 if (tag === 'li' && drop.hasClass('listitem-course')) { 763 if (!this.goingup) { 764 drop = drop.get('nextSibling'); 765 if (!drop) { 766 drop = e.drop.get('node'); 767 drop.get('parentNode').append(drag); 768 return false; 769 } 770 } 771 drop.get('parentNode').insertBefore(drag, drop); 772 e.drop.sizeShim(); 773 } 774 }, 775 776 /** 777 * The course has been dragged over a drop target. 778 * @method dropEnter 779 * @private 780 * @param {EventFacade} e 781 */ 782 dropEnter : function(e) { 783 var drop = e.drop.get('node'), 784 tag = drop.get('tagName').toLowerCase(); 785 if (tag === 'div') { 786 drop.ancestor('li.listitem-category').addClass('highlight'); 787 } 788 }, 789 790 /** 791 * The course has been dragged off a drop target. 792 * @method dropExit 793 * @private 794 * @param {EventFacade} e 795 */ 796 dropExit : function(e) { 797 var drop = e.drop.get('node'), 798 tag = drop.get('tagName').toLowerCase(); 799 if (tag === 'div') { 800 drop.ancestor('li.listitem-category').removeClass('highlight'); 801 } 802 }, 803 804 /** 805 * The course has been dropped on a target. 806 * @method dropHit 807 * @private 808 * @param {EventFacade} e 809 */ 810 dropHit : function(e) { 811 var drag = e.drag.get('node'), 812 drop = e.drop.get('node'), 813 iscategory = (drop.ancestor('.listitem-category') !== null), 814 iscourse = !iscategory && (drop.test('.listitem-course')), 815 managementconsole = this.get('console'), 816 categoryid, 817 category, 818 courseid, 819 course, 820 aftercourseid, 821 previoussibling, 822 previousid; 823 824 if (!drag.test('.listitem-course')) { 825 return false; 826 } 827 courseid = drag.getData('id'); 828 if (iscategory) { 829 categoryid = drop.ancestor('.listitem-category').getData('id'); 830 category = managementconsole.getCategoryById(categoryid); 831 if (category) { 832 course = managementconsole.getCourseById(courseid); 833 if (course) { 834 category.moveCourseTo(course); 835 } 836 } 837 } else if (iscourse || drop.ancestor('#course-listing')) { 838 course = managementconsole.getCourseById(courseid); 839 previoussibling = drag.get('previousSibling'); 840 aftercourseid = (previoussibling) ? previoussibling.getData('id') || 0 : 0; 841 previousid = (this.previoussibling) ? this.previoussibling.getData('id') : 0; 842 if (aftercourseid !== previousid) { 843 course.moveAfter(aftercourseid, previousid); 844 } 845 } else { 846 } 847 } 848 }; 849 Y.extend(DragDrop, Y.Base, DragDrop.prototype); 850 /** 851 * A managed course. 852 * 853 * @namespace M.course.management 854 * @class Item 855 * @constructor 856 * @extends Base 857 */ 858 function Item() { 859 Item.superclass.constructor.apply(this, arguments); 860 } 861 Item.NAME = 'moodle-course-management-item'; 862 Item.CSS_PREFIX = 'management-item'; 863 Item.ATTRS = { 864 /** 865 * The node for this item. 866 * @attribute node 867 * @type Node 868 */ 869 node : {}, 870 871 /** 872 * The management console. 873 * @attribute console 874 * @type Console 875 */ 876 console : {}, 877 878 /** 879 * Describes the type of this item. Should be set by the extending class. 880 * @attribute itemname 881 * @type {String} 882 * @default item 883 */ 884 itemname : { 885 value : 'item' 886 } 887 }; 888 Item.prototype = { 889 /** 890 * The highlight timeout for this item if there is one. 891 * @property highlighttimeout 892 * @protected 893 * @type Timeout 894 * @default null 895 */ 896 highlighttimeout : null, 897 898 /** 899 * Checks and parses an AJAX response for an item. 900 * 901 * @method checkAjaxResponse 902 * @protected 903 * @param {Number} transactionid The transaction ID of the AJAX request (unique) 904 * @param {Object} response The response from the AJAX request. 905 * @param {Object} args The arguments given to the request. 906 * @return {Object|Boolean} 907 */ 908 checkAjaxResponse : function(transactionid, response, args) { 909 if (response.status !== 200) { 910 return false; 911 } 912 if (transactionid === null || args === null) { 913 return false; 914 } 915 var outcome = Y.JSON.parse(response.responseText); 916 if (outcome.error !== false) { 917 new M.core.exception(outcome); 918 } 919 if (outcome.outcome === false) { 920 return false; 921 } 922 return outcome; 923 }, 924 925 /** 926 * Moves an item up by one. 927 * 928 * @method moveup 929 * @param {Number} transactionid The transaction ID of the AJAX request (unique) 930 * @param {Object} response The response from the AJAX request. 931 * @param {Object} args The arguments given to the request. 932 * @return {Boolean} 933 */ 934 moveup : function(transactionid, response, args) { 935 var node, 936 nodeup, 937 nodedown, 938 previous, 939 previousup, 940 previousdown, 941 tmpnode, 942 outcome = this.checkAjaxResponse(transactionid, response, args); 943 if (outcome === false) { 944 return false; 945 } 946 node = this.get('node'); 947 previous = node.previous('.listitem'); 948 if (previous) { 949 previous.insert(node, 'before'); 950 previousup = previous.one(' > div a.action-moveup'); 951 nodedown = node.one(' > div a.action-movedown'); 952 if (!previousup || !nodedown) { 953 // We can have two situations here: 954 // 1. previousup is not set and nodedown is not set. This happens when there are only two courses. 955 // 2. nodedown is not set. This happens when they are moving the bottom course up. 956 // node up and previous down should always be there. They would be required to trigger the action. 957 nodeup = node.one(' > div a.action-moveup'); 958 previousdown = previous.one(' > div a.action-movedown'); 959 if (!previousup && !nodedown) { 960 // Ok, must be two courses. We need to switch the up and down icons. 961 tmpnode = Y.Node.create('<a style="visibility:hidden;"> </a>'); 962 previousdown.replace(tmpnode); 963 nodeup.replace(previousdown); 964 tmpnode.replace(nodeup); 965 tmpnode.destroy(); 966 } else if (!nodedown) { 967 // previous down needs to be given to node. 968 nodeup.insert(previousdown, 'after'); 969 } 970 } 971 nodeup = node.one(' > div a.action-moveup'); 972 if (nodeup) { 973 // Try to re-focus on up. 974 nodeup.focus(); 975 } else { 976 // If we can't focus up we're at the bottom, try to focus on up. 977 nodedown = node.one(' > div a.action-movedown'); 978 if (nodedown) { 979 nodedown.focus(); 980 } 981 } 982 this.updated(true); 983 } else { 984 // Aha it succeeded but this is the top item in the list. Pagination is in play! 985 // Refresh to update the state of things. 986 window.location.reload(); 987 } 988 }, 989 990 /** 991 * Moves an item down by one. 992 * 993 * @method movedown 994 * @param {Number} transactionid The transaction ID of the AJAX request (unique) 995 * @param {Object} response The response from the AJAX request. 996 * @param {Object} args The arguments given to the request. 997 * @return {Boolean} 998 */ 999 movedown : function(transactionid, response, args) { 1000 var node, 1001 next, 1002 nodeup, 1003 nodedown, 1004 nextup, 1005 nextdown, 1006 tmpnode, 1007 outcome = this.checkAjaxResponse(transactionid, response, args); 1008 if (outcome === false) { 1009 return false; 1010 } 1011 node = this.get('node'); 1012 next = node.next('.listitem'); 1013 if (next) { 1014 node.insert(next, 'before'); 1015 nextdown = next.one(' > div a.action-movedown'); 1016 nodeup = node.one(' > div a.action-moveup'); 1017 if (!nextdown || !nodeup) { 1018 // next up and node down should always be there. They would be required to trigger the action. 1019 nextup = next.one(' > div a.action-moveup'); 1020 nodedown = node.one(' > div a.action-movedown'); 1021 if (!nextdown && !nodeup) { 1022 // We can have two situations here: 1023 // 1. nextdown is not set and nodeup is not set. This happens when there are only two courses. 1024 // 2. nodeup is not set. This happens when we are moving the first course down. 1025 // Ok, must be two courses. We need to switch the up and down icons. 1026 tmpnode = Y.Node.create('<a style="visibility:hidden;"> </a>'); 1027 nextup.replace(tmpnode); 1028 nodedown.replace(nextup); 1029 tmpnode.replace(nodedown); 1030 tmpnode.destroy(); 1031 } else if (!nodeup) { 1032 // next up needs to be given to node. 1033 nodedown.insert(nextup, 'before'); 1034 } 1035 } 1036 nodedown = node.one(' > div a.action-movedown'); 1037 if (nodedown) { 1038 // Try to ensure the up is focused again. 1039 nodedown.focus(); 1040 } else { 1041 // If we can't focus up we're at the top, try to focus on down. 1042 nodeup = node.one(' > div a.action-moveup'); 1043 if (nodeup) { 1044 nodeup.focus(); 1045 } 1046 } 1047 this.updated(true); 1048 } else { 1049 // Aha it succeeded but this is the bottom item in the list. Pagination is in play! 1050 // Refresh to update the state of things. 1051 window.location.reload(); 1052 } 1053 }, 1054 1055 /** 1056 * Makes an item visible. 1057 * 1058 * @method show 1059 * @param {Number} transactionid The transaction ID of the AJAX request (unique) 1060 * @param {Object} response The response from the AJAX request. 1061 * @param {Object} args The arguments given to the request. 1062 * @return {Boolean} 1063 */ 1064 show : function(transactionid, response, args) { 1065 var outcome = this.checkAjaxResponse(transactionid, response, args), 1066 hidebtn; 1067 if (outcome === false) { 1068 return false; 1069 } 1070 1071 this.markVisible(); 1072 hidebtn = this.get('node').one('a[data-action=hide]'); 1073 if (hidebtn) { 1074 hidebtn.focus(); 1075 } 1076 this.updated(); 1077 }, 1078 1079 /** 1080 * Marks the item as visible 1081 * @method markVisible 1082 */ 1083 markVisible : function() { 1084 this.get('node').setAttribute('data-visible', '1'); 1085 return true; 1086 }, 1087 1088 /** 1089 * Hides an item. 1090 * 1091 * @method hide 1092 * @param {Number} transactionid The transaction ID of the AJAX request (unique) 1093 * @param {Object} response The response from the AJAX request. 1094 * @param {Object} args The arguments given to the request. 1095 * @return {Boolean} 1096 */ 1097 hide : function(transactionid, response, args) { 1098 var outcome = this.checkAjaxResponse(transactionid, response, args), 1099 showbtn; 1100 if (outcome === false) { 1101 return false; 1102 } 1103 this.markHidden(); 1104 showbtn = this.get('node').one('a[data-action=show]'); 1105 if (showbtn) { 1106 showbtn.focus(); 1107 } 1108 this.updated(); 1109 }, 1110 1111 /** 1112 * Marks the item as hidden. 1113 * @method makeHidden 1114 */ 1115 markHidden : function() { 1116 this.get('node').setAttribute('data-visible', '0'); 1117 return true; 1118 }, 1119 1120 /** 1121 * Called when ever a node is updated. 1122 * 1123 * @method updated 1124 * @param {Boolean} moved True if this item was moved. 1125 */ 1126 updated : function(moved) { 1127 if (moved) { 1128 this.highlight(); 1129 } 1130 }, 1131 1132 /** 1133 * Highlights this option for a breif time. 1134 * 1135 * @method highlight 1136 */ 1137 highlight : function() { 1138 var node = this.get('node'); 1139 node.siblings('.highlight').removeClass('highlight'); 1140 node.addClass('highlight'); 1141 if (this.highlighttimeout) { 1142 window.clearTimeout(this.highlighttimeout); 1143 } 1144 this.highlighttimeout = window.setTimeout(function(){ 1145 node.removeClass('highlight'); 1146 }, 2500); 1147 } 1148 }; 1149 Y.extend(Item, Y.Base, Item.prototype); 1150 /** 1151 * A managed category. 1152 * 1153 * @namespace M.course.management 1154 * @class Category 1155 * @constructor 1156 * @extends Item 1157 */ 1158 function Category() { 1159 Category.superclass.constructor.apply(this, arguments); 1160 } 1161 Category.NAME = 'moodle-course-management-category'; 1162 Category.CSS_PREFIX = 'management-category'; 1163 Category.ATTRS = { 1164 /** 1165 * The category ID relating to this category. 1166 * @attribute categoryid 1167 * @type Number 1168 * @writeOnce 1169 * @default null 1170 */ 1171 categoryid : { 1172 getter : function (value, name) { 1173 if (value === null) { 1174 value = this.get('node').getData('id'); 1175 this.set(name, value); 1176 } 1177 return value; 1178 }, 1179 value : null, 1180 writeOnce : true 1181 }, 1182 1183 /** 1184 * True if this category is the currently selected category. 1185 * @attribute selected 1186 * @type Boolean 1187 * @default null 1188 */ 1189 selected : { 1190 getter : function(value, name) { 1191 if (value === null) { 1192 value = this.get('node').getData(name); 1193 if (value === null) { 1194 value = false; 1195 } 1196 this.set(name, value); 1197 } 1198 return value; 1199 }, 1200 value : null 1201 }, 1202 1203 /** 1204 * An array of courses belonging to this category. 1205 * @attribute courses 1206 * @type Course[] 1207 * @default Array 1208 */ 1209 courses : { 1210 validator : function(val) { 1211 return Y.Lang.isArray(val); 1212 }, 1213 value : [] 1214 } 1215 }; 1216 Category.prototype = { 1217 /** 1218 * Initialises an instance of a Category. 1219 * @method initializer 1220 */ 1221 initializer : function() { 1222 this.set('itemname', 'category'); 1223 }, 1224 1225 /** 1226 * Returns the name of the category. 1227 * @method getName 1228 * @return {String} 1229 */ 1230 getName : function() { 1231 return this.get('node').one('a.categoryname').get('innerHTML'); 1232 }, 1233 1234 /** 1235 * Registers a course as belonging to this category. 1236 * @method registerCourse 1237 * @param {Course} course 1238 */ 1239 registerCourse : function(course) { 1240 var courses = this.get('courses'); 1241 courses.push(course); 1242 this.set('courses', courses); 1243 }, 1244 1245 /** 1246 * Handles a category related event. 1247 * 1248 * @method handle 1249 * @param {String} action 1250 * @param {EventFacade} e 1251 * @return {Boolean} 1252 */ 1253 handle : function(action, e) { 1254 var catarg = {categoryid : this.get('categoryid')}, 1255 selected = this.get('console').get('activecategoryid'); 1256 if (selected && selected !== catarg.categoryid) { 1257 catarg.selectedcategory = selected; 1258 } 1259 switch (action) { 1260 case 'moveup': 1261 e.preventDefault(); 1262 this.get('console').performAjaxAction('movecategoryup', catarg, this.moveup, this); 1263 break; 1264 case 'movedown': 1265 e.preventDefault(); 1266 this.get('console').performAjaxAction('movecategorydown', catarg, this.movedown, this); 1267 break; 1268 case 'show': 1269 e.preventDefault(); 1270 this.get('console').performAjaxAction('showcategory', catarg, this.show, this); 1271 break; 1272 case 'hide': 1273 e.preventDefault(); 1274 this.get('console').performAjaxAction('hidecategory', catarg, this.hide, this); 1275 break; 1276 case 'expand': 1277 e.preventDefault(); 1278 if (this.get('node').getData('expanded') === '0') { 1279 this.get('node').setAttribute('data-expanded', '1').setData('expanded', 'true'); 1280 this.get('console').performAjaxAction('getsubcategorieshtml', catarg, this.loadSubcategories, this); 1281 } 1282 this.expand(); 1283 break; 1284 case 'collapse': 1285 e.preventDefault(); 1286 this.collapse(); 1287 break; 1288 case 'select': 1289 var c = this.get('console'), 1290 movecategoryto = c.get('categorylisting').one('#menumovecategoriesto'); 1291 // If any category is selected and there are more then one categories. 1292 if (movecategoryto) { 1293 if (c.isCategorySelected(e.currentTarget) && 1294 c.get('categories').length > 1) { 1295 movecategoryto.removeAttribute('disabled'); 1296 } else { 1297 movecategoryto.setAttribute('disabled', true); 1298 } 1299 c.handleBulkSortByaction(); 1300 } 1301 break; 1302 default: 1303 return false; 1304 } 1305 }, 1306 1307 /** 1308 * Expands the category making its sub categories visible. 1309 * @method expand 1310 */ 1311 expand : function() { 1312 var node = this.get('node'), 1313 action = node.one('a[data-action=expand]'), 1314 ul = node.one('ul[role=group]'); 1315 node.removeClass('collapsed').setAttribute('aria-expanded', 'true'); 1316 action.setAttribute('data-action', 'collapse').setAttrs({ 1317 title : M.util.get_string('collapsecategory', 'moodle', this.getName()) 1318 }).one('img').setAttrs({ 1319 src : M.util.image_url('t/switch_minus', 'moodle'), 1320 alt : M.util.get_string('collapse', 'moodle') 1321 }); 1322 if (ul) { 1323 ul.setAttribute('aria-hidden', 'false'); 1324 } 1325 this.get('console').performAjaxAction('expandcategory', {categoryid : this.get('categoryid')}, null, this); 1326 }, 1327 1328 /** 1329 * Collapses the category making its sub categories hidden. 1330 * @method collapse 1331 */ 1332 collapse : function() { 1333 var node = this.get('node'), 1334 action = node.one('a[data-action=collapse]'), 1335 ul = node.one('ul[role=group]'); 1336 node.addClass('collapsed').setAttribute('aria-expanded', 'false'); 1337 action.setAttribute('data-action', 'expand').setAttrs({ 1338 title : M.util.get_string('expandcategory', 'moodle', this.getName()) 1339 }).one('img').setAttrs({ 1340 src : M.util.image_url('t/switch_plus', 'moodle'), 1341 alt : M.util.get_string('expand', 'moodle') 1342 }); 1343 if (ul) { 1344 ul.setAttribute('aria-hidden', 'true'); 1345 } 1346 this.get('console').performAjaxAction('collapsecategory', {categoryid : this.get('categoryid')}, null, this); 1347 }, 1348 1349 /** 1350 * Loads sub categories provided by an AJAX request.. 1351 * 1352 * @method loadSubcategories 1353 * @protected 1354 * @param {Number} transactionid The transaction ID of the AJAX request (unique) 1355 * @param {Object} response The response from the AJAX request. 1356 * @param {Object} args The arguments given to the request. 1357 * @return {Boolean} Returns true on success - false otherwise. 1358 */ 1359 loadSubcategories : function(transactionid, response, args) { 1360 var outcome = this.checkAjaxResponse(transactionid, response, args), 1361 node = this.get('node'), 1362 managementconsole = this.get('console'), 1363 ul, 1364 actionnode; 1365 if (outcome === false) { 1366 return false; 1367 } 1368 node.append(outcome.html); 1369 managementconsole.initialiseCategories(node); 1370 if (M.core && M.core.actionmenu && M.core.actionmenu.newDOMNode) { 1371 M.core.actionmenu.newDOMNode(node); 1372 } 1373 ul = node.one('ul[role=group]'); 1374 actionnode = node.one('a[data-action=collapse]'); 1375 if (ul && actionnode) { 1376 actionnode.setAttribute('aria-controls', ul.generateID()); 1377 } 1378 return true; 1379 }, 1380 1381 /** 1382 * Moves the course to this category. 1383 * 1384 * @method moveCourseTo 1385 * @param {Course} course 1386 */ 1387 moveCourseTo : function(course) { 1388 var self = this; 1389 Y.use('moodle-core-notification-confirm', function() { 1390 var confirm = new M.core.confirm({ 1391 title : M.util.get_string('confirm', 'moodle'), 1392 question : M.util.get_string('confirmcoursemove', 'moodle', { 1393 course : course.getName(), 1394 category : self.getName() 1395 }), 1396 yesLabel : M.util.get_string('move', 'moodle'), 1397 noLabel : M.util.get_string('cancel', 'moodle') 1398 }); 1399 confirm.on('complete-yes', function() { 1400 confirm.hide(); 1401 confirm.destroy(); 1402 this.get('console').performAjaxAction('movecourseintocategory', { 1403 categoryid : this.get('categoryid'), 1404 courseid : course.get('courseid') 1405 }, this.completeMoveCourse, this); 1406 }, self); 1407 confirm.show(); 1408 }); 1409 }, 1410 1411 /** 1412 * Completes moving a course to this category. 1413 * @method completeMoveCourse 1414 * @protected 1415 * @param {Number} transactionid The transaction ID of the AJAX request (unique) 1416 * @param {Object} response The response from the AJAX request. 1417 * @param {Object} args The arguments given to the request. 1418 * @return {Boolean} 1419 */ 1420 completeMoveCourse : function(transactionid, response, args) { 1421 var outcome = this.checkAjaxResponse(transactionid, response, args), 1422 managementconsole = this.get('console'), 1423 category, 1424 course, 1425 totals; 1426 if (outcome === false) { 1427 return false; 1428 } 1429 course = managementconsole.getCourseById(args.courseid); 1430 if (!course) { 1431 return false; 1432 } 1433 this.highlight(); 1434 if (course) { 1435 if (outcome.paginationtotals) { 1436 totals = managementconsole.get('courselisting').one('.listing-pagination-totals'); 1437 if (totals) { 1438 totals.set('innerHTML', outcome.paginationtotals); 1439 } 1440 } 1441 if (outcome.totalcatcourses !== 'undefined') { 1442 totals = this.get('node').one('.course-count span'); 1443 if (totals) { 1444 totals.set('innerHTML', totals.get('innerHTML').replace(/^\d+/, outcome.totalcatcourses)); 1445 } 1446 } 1447 if (typeof outcome.fromcatcoursecount !== 'undefined') { 1448 category = managementconsole.get('activecategoryid'); 1449 category = managementconsole.getCategoryById(category); 1450 if (category) { 1451 totals = category.get('node').one('.course-count span'); 1452 if (totals) { 1453 totals.set('innerHTML', totals.get('innerHTML').replace(/^\d+/, outcome.fromcatcoursecount)); 1454 } 1455 } 1456 } 1457 course.remove(); 1458 } 1459 return true; 1460 }, 1461 1462 /** 1463 * Makes an item visible. 1464 * 1465 * @method show 1466 * @param {Number} transactionid The transaction ID of the AJAX request (unique) 1467 * @param {Object} response The response from the AJAX request. 1468 * @param {Object} args The arguments given to the request. 1469 * @return {Boolean} 1470 */ 1471 show : function(transactionid, response, args) { 1472 var outcome = this.checkAjaxResponse(transactionid, response, args), 1473 hidebtn; 1474 if (outcome === false) { 1475 return false; 1476 } 1477 1478 this.markVisible(); 1479 hidebtn = this.get('node').one('a[data-action=hide]'); 1480 if (hidebtn) { 1481 hidebtn.focus(); 1482 } 1483 if (outcome.categoryvisibility) { 1484 this.updateChildVisibility(outcome.categoryvisibility); 1485 } 1486 if (outcome.coursevisibility) { 1487 this.updateCourseVisiblity(outcome.coursevisibility); 1488 } 1489 this.updated(); 1490 }, 1491 1492 /** 1493 * Hides an item. 1494 * 1495 * @method hide 1496 * @param {Number} transactionid The transaction ID of the AJAX request (unique) 1497 * @param {Object} response The response from the AJAX request. 1498 * @param {Object} args The arguments given to the request. 1499 * @return {Boolean} 1500 */ 1501 hide : function(transactionid, response, args) { 1502 var outcome = this.checkAjaxResponse(transactionid, response, args), 1503 showbtn; 1504 if (outcome === false) { 1505 return false; 1506 } 1507 this.markHidden(); 1508 showbtn = this.get('node').one('a[data-action=show]'); 1509 if (showbtn) { 1510 showbtn.focus(); 1511 } 1512 if (outcome.categoryvisibility) { 1513 this.updateChildVisibility(outcome.categoryvisibility); 1514 } 1515 if (outcome.coursevisibility) { 1516 this.updateCourseVisiblity(outcome.coursevisibility); 1517 } 1518 this.updated(); 1519 }, 1520 1521 /** 1522 * Updates the visibility of child courses if required. 1523 * @method updateCourseVisiblity 1524 * @chainable 1525 * @param courses 1526 */ 1527 updateCourseVisiblity : function(courses) { 1528 var managementconsole = this.get('console'), 1529 key, 1530 course; 1531 try { 1532 for (key in courses) { 1533 if (typeof courses[key] === 'object') { 1534 course = managementconsole.getCourseById(courses[key].id); 1535 if (course) { 1536 if (courses[key].visible === "1") { 1537 course.markVisible(); 1538 } else { 1539 course.markHidden(); 1540 } 1541 } 1542 } 1543 } 1544 } catch (err) { 1545 } 1546 return this; 1547 }, 1548 1549 /** 1550 * Updates the visibility of subcategories if required. 1551 * @method updateChildVisibility 1552 * @chainable 1553 * @param categories 1554 */ 1555 updateChildVisibility : function(categories) { 1556 var managementconsole = this.get('console'), 1557 key, 1558 category; 1559 try { 1560 for (key in categories) { 1561 if (typeof categories[key] === 'object') { 1562 category = managementconsole.getCategoryById(categories[key].id); 1563 if (category) { 1564 if (categories[key].visible === "1") { 1565 category.markVisible(); 1566 } else { 1567 category.markHidden(); 1568 } 1569 } 1570 } 1571 } 1572 } catch (err) { 1573 } 1574 return this; 1575 } 1576 }; 1577 Y.extend(Category, Item, Category.prototype); 1578 /** 1579 * A managed course. 1580 * 1581 * @namespace M.course.management 1582 * @class Course 1583 * @constructor 1584 * @extends Item 1585 */ 1586 function Course() { 1587 Course.superclass.constructor.apply(this, arguments); 1588 } 1589 Course.NAME = 'moodle-course-management-course'; 1590 Course.CSS_PREFIX = 'management-course'; 1591 Course.ATTRS = { 1592 1593 /** 1594 * The course ID of this course. 1595 * @attribute courseid 1596 * @type Number 1597 */ 1598 courseid : {}, 1599 1600 /** 1601 * True if this is the selected course. 1602 * @attribute selected 1603 * @type Boolean 1604 * @default null 1605 */ 1606 selected : { 1607 getter : function(value, name) { 1608 if (value === null) { 1609 value = this.get('node').getData(name); 1610 this.set(name, value); 1611 } 1612 return value; 1613 }, 1614 value : null 1615 }, 1616 node : { 1617 1618 }, 1619 /** 1620 * The management console tracking this course. 1621 * @attribute console 1622 * @type Console 1623 * @writeOnce 1624 */ 1625 console : { 1626 writeOnce : 'initOnly' 1627 }, 1628 1629 /** 1630 * The category this course belongs to. 1631 * @attribute category 1632 * @type Category 1633 * @writeOnce 1634 */ 1635 category : { 1636 writeOnce : 'initOnly' 1637 } 1638 }; 1639 Course.prototype = { 1640 /** 1641 * Initialises the new course instance. 1642 * @method initializer 1643 */ 1644 initializer : function() { 1645 var node = this.get('node'), 1646 category = this.get('category'); 1647 this.set('courseid', node.getData('id')); 1648 if (category && category.registerCourse) { 1649 category.registerCourse(this); 1650 } 1651 this.set('itemname', 'course'); 1652 }, 1653 1654 /** 1655 * Returns the name of the course. 1656 * @method getName 1657 * @return {String} 1658 */ 1659 getName : function() { 1660 return this.get('node').one('a.coursename').get('innerHTML'); 1661 }, 1662 1663 /** 1664 * Handles an event relating to this course. 1665 * @method handle 1666 * @param {String} action 1667 * @param {EventFacade} e 1668 * @return {Boolean} 1669 */ 1670 handle : function(action, e) { 1671 var managementconsole = this.get('console'), 1672 args = {courseid : this.get('courseid')}; 1673 switch (action) { 1674 case 'moveup': 1675 e.halt(); 1676 managementconsole.performAjaxAction('movecourseup', args, this.moveup, this); 1677 break; 1678 case 'movedown': 1679 e.halt(); 1680 managementconsole.performAjaxAction('movecoursedown', args, this.movedown, this); 1681 break; 1682 case 'show': 1683 e.halt(); 1684 managementconsole.performAjaxAction('showcourse', args, this.show, this); 1685 break; 1686 case 'hide': 1687 e.halt(); 1688 managementconsole.performAjaxAction('hidecourse', args, this.hide, this); 1689 break; 1690 case 'select': 1691 var c = this.get('console'), 1692 movetonode = c.get('courselisting').one('#menumovecoursesto'); 1693 if (movetonode) { 1694 if (c.isCourseSelected(e.currentTarget)) { 1695 movetonode.removeAttribute('disabled'); 1696 } else { 1697 movetonode.setAttribute('disabled', true); 1698 } 1699 } 1700 break; 1701 default: 1702 return false; 1703 } 1704 }, 1705 1706 /** 1707 * Removes this course. 1708 * @method remove 1709 */ 1710 remove : function() { 1711 this.get('console').removeCourseById(this.get('courseid')); 1712 this.get('node').remove(); 1713 }, 1714 1715 /** 1716 * Moves this course after another course. 1717 * 1718 * @method moveAfter 1719 * @param {Number} moveaftercourse The course to move after or 0 to put it at the top. 1720 * @param {Number} previousid the course it was previously after in case we need to revert. 1721 */ 1722 moveAfter : function(moveaftercourse, previousid) { 1723 var managementconsole = this.get('console'), 1724 args = { 1725 courseid : this.get('courseid'), 1726 moveafter : moveaftercourse, 1727 previous : previousid 1728 }; 1729 managementconsole.performAjaxAction('movecourseafter', args, this.moveAfterResponse, this); 1730 }, 1731 1732 /** 1733 * Performs the actual move. 1734 * 1735 * @method moveAfterResponse 1736 * @protected 1737 * @param {Number} transactionid The transaction ID for the request. 1738 * @param {Object} response The response to the request. 1739 * @param {Objects} args The arguments that were given with the request. 1740 * @return {Boolean} 1741 */ 1742 moveAfterResponse : function(transactionid, response, args) { 1743 var outcome = this.checkAjaxResponse(transactionid, response, args), 1744 node = this.get('node'), 1745 previous; 1746 if (outcome === false) { 1747 previous = node.ancestor('ul').one('li[data-id='+args.previous+']'); 1748 if (previous) { 1749 // After the last previous. 1750 previous.insertAfter(node, 'after'); 1751 } else { 1752 // Start of the list. 1753 node.ancestor('ul').one('li').insert(node, 'before'); 1754 } 1755 return false; 1756 } 1757 this.highlight(); 1758 } 1759 }; 1760 Y.extend(Course, Item, Course.prototype); 1761 1762 1763 }, '@VERSION@', { 1764 "requires": [ 1765 "base", 1766 "node", 1767 "io-base", 1768 "moodle-core-notification-exception", 1769 "json-parse", 1770 "dd-constrain", 1771 "dd-proxy", 1772 "dd-drop", 1773 "dd-delegate", 1774 "node-event-delegate" 1775 ] 1776 });
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 20:29:05 2014 | Cross-referenced by PHPXref 0.7.1 |