[ Index ]

PHP Cross Reference of Unnamed Project

title

Body

[close]

/admin/tool/lp/amd/src/ -> competencyactions.js (source)

   1  // This file is part of Moodle - http://moodle.org/
   2  //
   3  // Moodle is free software: you can redistribute it and/or modify
   4  // it under the terms of the GNU General Public License as published by
   5  // the Free Software Foundation, either version 3 of the License, or
   6  // (at your option) any later version.
   7  //
   8  // Moodle is distributed in the hope that it will be useful,
   9  // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11  // GNU General Public License for more details.
  12  //
  13  // You should have received a copy of the GNU General Public License
  14  // along with Moodle.  If not, see <http://www.gnu.org/licenses/>.
  15  
  16  /**
  17   * Handle selection changes and actions on the competency tree.
  18   *
  19   * @module     tool_lp/competencyactions
  20   * @package    tool_lp
  21   * @copyright  2015 Damyon Wiese <damyon@moodle.com>
  22   * @license    http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later
  23   */
  24  define(['jquery',
  25          'core/url',
  26          'core/templates',
  27          'core/notification',
  28          'core/str',
  29          'core/ajax',
  30          'tool_lp/dragdrop-reorder',
  31          'tool_lp/tree',
  32          'tool_lp/dialogue',
  33          'tool_lp/menubar',
  34          'tool_lp/competencypicker',
  35          'tool_lp/competency_outcomes',
  36          'tool_lp/competencyruleconfig'],
  37         function($, url, templates, notification, str, ajax, dragdrop, Ariatree, Dialogue, menubar, Picker, Outcomes, RuleConfig) {
  38  
  39      // Private variables and functions.
  40      /** @var {Object} treeModel - This is an object representing the nodes in the tree. */
  41      var treeModel = null;
  42      /** @var {Node} moveSource - The start of a drag operation */
  43      var moveSource = null;
  44      /** @var {Node} moveTarget - The end of a drag operation */
  45      var moveTarget = null;
  46      /** @var {Number} pageContextId The page context ID. */
  47      var pageContextId;
  48      /** @type {Object} Picker instance. */
  49      var pickerInstance;
  50      /** @type {Object} Rule config instance. */
  51      var ruleConfigInstance;
  52      /** @type {Object} The competency we're picking a relation to. */
  53      var relatedTarget;
  54      /** @type {Object} Taxonomy constants indexed per level. */
  55      var taxonomiesConstants;
  56      /** @type {Array} The rules modules. Values are object containing type, namd and amd. */
  57      var rulesModules;
  58      /** @type {Number} the selected competency ID. */
  59      var selectedCompetencyId = null;
  60  
  61      /**
  62       * Respond to choosing the "Add" menu item for the selected node in the tree.
  63       * @method addHandler
  64       */
  65      var addHandler = function() {
  66          var parent = $('[data-region="competencyactions"]').data('competency');
  67  
  68          var params = {
  69              competencyframeworkid: treeModel.getCompetencyFrameworkId(),
  70              pagecontextid: pageContextId
  71          };
  72  
  73          if (parent !== null) {
  74              // We are adding at a sub node.
  75              params.parentid = parent.id;
  76          }
  77  
  78          var relocate = function() {
  79              var queryparams = $.param(params);
  80              window.location = url.relativeUrl('/admin/tool/lp/editcompetency.php?' + queryparams);
  81          };
  82  
  83          if (parent !== null && treeModel.hasRule(parent.id)) {
  84              str.get_strings([
  85                  {key: 'confirm', component: 'moodle'},
  86                  {key: 'addingcompetencywillresetparentrule', component: 'tool_lp', param: parent.shortname},
  87                  {key: 'yes', component: 'core'},
  88                  {key: 'no', component: 'core'}
  89              ]).done(function(strings) {
  90                  notification.confirm(
  91                      strings[0],
  92                      strings[1],
  93                      strings[2],
  94                      strings[3],
  95                      relocate
  96                  );
  97              }).fail(notification.exception);
  98          } else {
  99              relocate();
 100          }
 101      };
 102  
 103      /**
 104       * A source and destination has been chosen - so time to complete a move.
 105       * @method doMove
 106       */
 107      var doMove = function() {
 108          var frameworkid = $('[data-region="filtercompetencies"]').data('frameworkid');
 109          var requests = ajax.call([{
 110              methodname: 'core_competency_set_parent_competency',
 111              args: {competencyid: moveSource, parentid: moveTarget}
 112          }, {
 113              methodname: 'tool_lp_data_for_competencies_manage_page',
 114              args: {competencyframeworkid: frameworkid,
 115                      search: $('[data-region="filtercompetencies"] input').val()}
 116          }]);
 117          requests[1].done(reloadPage).fail(notification.exception);
 118      };
 119  
 120      /**
 121       * Confirms a competency move.
 122       *
 123       * @method confirmMove
 124       */
 125      var confirmMove = function() {
 126          moveTarget = typeof moveTarget === "undefined" ? 0 : moveTarget;
 127          if (moveTarget == moveSource) {
 128              // No move to do.
 129              return;
 130          }
 131  
 132          var targetComp = treeModel.getCompetency(moveTarget) || {},
 133              sourceComp = treeModel.getCompetency(moveSource) || {},
 134              confirmMessage = 'movecompetencywillresetrules',
 135              showConfirm = false;
 136  
 137          // We shouldn't be moving the competency to the same parent.
 138          if (sourceComp.parentid == moveTarget) {
 139              return;
 140          }
 141  
 142          // If we are moving to a child of self.
 143          if (targetComp.path && targetComp.path.indexOf('/' + sourceComp.id + '/') >= 0) {
 144              confirmMessage = 'movecompetencytochildofselfwillresetrules';
 145  
 146              // Show a confirmation if self has rules, as they'll disappear.
 147              showConfirm = showConfirm || treeModel.hasRule(sourceComp.id);
 148          }
 149  
 150          // Show a confirmation if the current parent, or the destination have rules.
 151          showConfirm = showConfirm || (treeModel.hasRule(targetComp.id) || treeModel.hasRule(sourceComp.parentid));
 152  
 153          // Show confirm, and/or do the things.
 154          if (showConfirm) {
 155              str.get_strings([
 156                  {key: 'confirm', component: 'moodle'},
 157                  {key: confirmMessage, component: 'tool_lp'},
 158                  {key: 'yes', component: 'moodle'},
 159                  {key: 'no', component: 'moodle'}
 160              ]).done(function(strings) {
 161                  notification.confirm(
 162                      strings[0], // Confirm.
 163                      strings[1], // Delete competency X?
 164                      strings[2], // Delete.
 165                      strings[3], // Cancel.
 166                      doMove
 167                  );
 168              }).fail(notification.exception);
 169  
 170          } else {
 171              doMove();
 172          }
 173      };
 174  
 175      /**
 176       * A move competency popup was opened - initialise the aria tree in it.
 177       * @method initMovePopup
 178       * @param {dialogue} popup The tool_lp/dialogue that was created.
 179       */
 180      var initMovePopup = function(popup) {
 181          var body = $(popup.getContent());
 182          var treeRoot = body.find('[data-enhance=movetree]');
 183          var tree = new Ariatree(treeRoot, false);
 184          tree.on('selectionchanged', function(evt, params) {
 185              var target = params.selected;
 186              moveTarget = $(target).data('id');
 187          });
 188          treeRoot.show();
 189  
 190          body.on('click', '[data-action="move"]', function() {
 191            popup.close();
 192            confirmMove();
 193          });
 194          body.on('click', '[data-action="cancel"]', function() {
 195            popup.close();
 196          });
 197      };
 198  
 199      /**
 200       * Turn a flat list of competencies into a tree structure (recursive).
 201       * @method addCompetencyChildren
 202       * @param {Object} parent The current parent node in the tree
 203       * @param {Object[]} competencies The flat list of competencies
 204       */
 205      var addCompetencyChildren = function(parent, competencies) {
 206          var i;
 207  
 208          for (i = 0; i < competencies.length; i++) {
 209              if (competencies[i].parentid == parent.id) {
 210                  parent.haschildren = true;
 211                  competencies[i].children = [];
 212                  competencies[i].haschildren = false;
 213                  parent.children[parent.children.length] = competencies[i];
 214                  addCompetencyChildren(competencies[i], competencies);
 215              }
 216          }
 217      };
 218  
 219      /**
 220       * A node was chosen and "Move" was selected from the menu. Open a popup to select the target.
 221       * @param {Event} e
 222       * @method moveHandler
 223       */
 224      var moveHandler = function(e) {
 225          e.preventDefault();
 226          var competency = $('[data-region="competencyactions"]').data('competency');
 227  
 228          // Remember what we are moving.
 229          moveSource = competency.id;
 230  
 231          // Load data for the template.
 232          var requests = ajax.call([
 233              {
 234                  methodname: 'core_competency_search_competencies',
 235                  args: {
 236                      competencyframeworkid: competency.competencyframeworkid,
 237                      searchtext: ''
 238                  }
 239              }, {
 240                  methodname: 'core_competency_read_competency_framework',
 241                  args: {
 242                      id: competency.competencyframeworkid
 243                  }
 244              }
 245          ]);
 246  
 247          // When all data has arrived, continue.
 248          $.when.apply(null, requests).done(function(competencies, framework) {
 249  
 250              // Expand the list of competencies into a tree.
 251              var i;
 252              var competenciestree = [];
 253              for (i = 0; i < competencies.length; i++) {
 254                  var onecompetency = competencies[i];
 255                  if (onecompetency.parentid == "0") {
 256                      onecompetency.children = [];
 257                      onecompetency.haschildren = 0;
 258                      competenciestree[competenciestree.length] = onecompetency;
 259                      addCompetencyChildren(onecompetency, competencies);
 260                  }
 261              }
 262  
 263              str.get_strings([
 264                  {key: 'movecompetency', component: 'tool_lp', param: competency.shortname},
 265                  {key: 'move', component: 'tool_lp'},
 266                  {key: 'cancel', component: 'moodle'}
 267              ]).done(function(strings) {
 268  
 269                  var context = {
 270                      framework: framework,
 271                      competencies: competenciestree
 272                  };
 273  
 274                  templates.render('tool_lp/competencies_move_tree', context)
 275                     .done(function(tree) {
 276                         new Dialogue(
 277                             strings[0], // Move competency x.
 278                             tree, // The move tree.
 279                             initMovePopup
 280                         );
 281  
 282                     }).fail(notification.exception);
 283  
 284             }).fail(notification.exception);
 285  
 286          }).fail(notification.exception);
 287  
 288      };
 289  
 290      /**
 291       * Edit the selected competency.
 292       * @method editHandler
 293       */
 294      var editHandler = function() {
 295          var competency = $('[data-region="competencyactions"]').data('competency');
 296  
 297          var params = {
 298              competencyframeworkid: treeModel.getCompetencyFrameworkId(),
 299              id: competency.id,
 300              parentid: competency.parentid,
 301              pagecontextid: pageContextId
 302          };
 303  
 304          var queryparams = $.param(params);
 305          window.location = url.relativeUrl('/admin/tool/lp/editcompetency.php?' + queryparams);
 306      };
 307  
 308      /**
 309       * Re-render the page with the latest data.
 310       * @param {Object} context
 311       * @method reloadPage
 312       */
 313      var reloadPage = function(context) {
 314          templates.render('tool_lp/manage_competencies_page', context)
 315              .done(function(newhtml, newjs) {
 316                  $('[data-region="managecompetencies"]').replaceWith(newhtml);
 317                  templates.runTemplateJS(newjs);
 318              })
 319             .fail(notification.exception);
 320      };
 321  
 322      /**
 323       * Perform a search and render the page with the new search results.
 324       * @param {Event} e
 325       * @method updateSearchHandler
 326       */
 327      var updateSearchHandler = function(e) {
 328          e.preventDefault();
 329  
 330          var frameworkid = $('[data-region="filtercompetencies"]').data('frameworkid');
 331  
 332          var requests = ajax.call([{
 333              methodname: 'tool_lp_data_for_competencies_manage_page',
 334              args: {competencyframeworkid: frameworkid,
 335                      search: $('[data-region="filtercompetencies"] input').val()}
 336          }]);
 337          requests[0].done(reloadPage).fail(notification.exception);
 338      };
 339  
 340      /**
 341       * Move a competency "up". This only affects the sort order within the same branch of the tree.
 342       * @method moveUpHandler
 343       */
 344      var moveUpHandler = function() {
 345          // We are chaining ajax requests here.
 346          var competency = $('[data-region="competencyactions"]').data('competency');
 347          var requests = ajax.call([{
 348              methodname: 'core_competency_move_up_competency',
 349              args: {id: competency.id}
 350          }, {
 351              methodname: 'tool_lp_data_for_competencies_manage_page',
 352              args: {competencyframeworkid: competency.competencyframeworkid,
 353                      search: $('[data-region="filtercompetencies"] input').val()}
 354          }]);
 355          requests[1].done(reloadPage).fail(notification.exception);
 356      };
 357  
 358      /**
 359       * Move a competency "down". This only affects the sort order within the same branch of the tree.
 360       * @method moveDownHandler
 361       */
 362      var moveDownHandler = function() {
 363          // We are chaining ajax requests here.
 364          var competency = $('[data-region="competencyactions"]').data('competency');
 365          var requests = ajax.call([{
 366              methodname: 'core_competency_move_down_competency',
 367              args: {id: competency.id}
 368          }, {
 369              methodname: 'tool_lp_data_for_competencies_manage_page',
 370              args: {competencyframeworkid: competency.competencyframeworkid,
 371                      search: $('[data-region="filtercompetencies"] input').val()}
 372          }]);
 373          requests[1].done(reloadPage).fail(notification.exception);
 374      };
 375  
 376      /**
 377       * Open a dialogue to show all the courses using the selected competency.
 378       * @method seeCoursesHandler
 379       */
 380      var seeCoursesHandler = function() {
 381          var competency = $('[data-region="competencyactions"]').data('competency');
 382  
 383          var requests = ajax.call([{
 384              methodname: 'tool_lp_list_courses_using_competency',
 385              args: {id: competency.id}
 386          }]);
 387  
 388          requests[0].done(function(courses) {
 389              var context = {
 390                  courses: courses
 391              };
 392              templates.render('tool_lp/linked_courses_summary', context).done(function(html) {
 393                  str.get_string('linkedcourses', 'tool_lp').done(function(linkedcourses) {
 394                      new Dialogue(
 395                          linkedcourses, // Title.
 396                          html, // The linked courses.
 397                          initMovePopup
 398                      );
 399                  }).fail(notification.exception);
 400              }).fail(notification.exception);
 401          }).fail(notification.exception);
 402      };
 403  
 404      /**
 405       * Open a competencies popup to relate competencies.
 406       *
 407       * @method relateCompetenciesHandler
 408       */
 409      var relateCompetenciesHandler = function() {
 410          relatedTarget = $('[data-region="competencyactions"]').data('competency');
 411  
 412          if (!pickerInstance) {
 413              pickerInstance = new Picker(pageContextId, relatedTarget.competencyframeworkid);
 414              pickerInstance.on('save', function(e, data) {
 415                  var compIds = data.competencyIds;
 416  
 417                  var calls = [];
 418                  $.each(compIds, function(index, value) {
 419                      calls.push({
 420                          methodname: 'core_competency_add_related_competency',
 421                          args: {competencyid: value, relatedcompetencyid: relatedTarget.id}
 422                      });
 423                  });
 424  
 425                  calls.push({
 426                      methodname: 'tool_lp_data_for_related_competencies_section',
 427                      args: {competencyid: relatedTarget.id}
 428                  });
 429  
 430                  var promises = ajax.call(calls);
 431  
 432                  promises[calls.length - 1].then(function(context) {
 433                      return templates.render('tool_lp/related_competencies', context).done(function(html, js) {
 434                          $('[data-region="relatedcompetencies"]').replaceWith(html);
 435                          templates.runTemplateJS(js);
 436                          updatedRelatedCompetencies();
 437                      });
 438                  }, notification.exception);
 439              });
 440          }
 441  
 442          pickerInstance.setDisallowedCompetencyIDs([relatedTarget.id]);
 443          pickerInstance.display();
 444      };
 445  
 446      var ruleConfigHandler = function(e) {
 447          e.preventDefault();
 448          relatedTarget = $('[data-region="competencyactions"]').data('competency');
 449          ruleConfigInstance.setTargetCompetencyId(relatedTarget.id);
 450          ruleConfigInstance.display();
 451      };
 452  
 453      var ruleConfigSaveHandler = function(e, config) {
 454          var update = {
 455              id: relatedTarget.id,
 456              shortname: relatedTarget.shortname,
 457              idnumber: relatedTarget.idnumber,
 458              description: relatedTarget.description,
 459              descriptionformat: relatedTarget.descriptionformat,
 460              ruletype: config.ruletype,
 461              ruleoutcome: config.ruleoutcome,
 462              ruleconfig: config.ruleconfig
 463          };
 464          var promise = ajax.call([{
 465              methodname: 'core_competency_update_competency',
 466              args: {competency: update}
 467          }]);
 468          promise[0].then(function(result) {
 469              if (result) {
 470                  relatedTarget.ruletype = config.ruletype;
 471                  relatedTarget.ruleoutcome = config.ruleoutcome;
 472                  relatedTarget.ruleconfig = config.ruleconfig;
 473                  renderCompetencySummary(relatedTarget);
 474              }
 475          }, notification.exception);
 476      };
 477  
 478      /**
 479       * Delete a competency.
 480       * @method doDelete
 481       */
 482      var doDelete = function() {
 483          // We are chaining ajax requests here.
 484          var competency = $('[data-region="competencyactions"]').data('competency');
 485          var requests = ajax.call([{
 486              methodname: 'core_competency_delete_competency',
 487              args: {id: competency.id}
 488          }, {
 489              methodname: 'tool_lp_data_for_competencies_manage_page',
 490              args: {competencyframeworkid: competency.competencyframeworkid,
 491                      search: $('[data-region="filtercompetencies"] input').val()}
 492          }]);
 493          requests[0].done(function(success) {
 494              if (success === false) {
 495                  str.get_strings([
 496                  {key: 'competencycannotbedeleted', component: 'tool_lp', param: competency.shortname},
 497                  {key: 'cancel', component: 'moodle'}
 498                  ]).done(function(strings) {
 499                      notification.alert(
 500                          null,
 501                          strings[0]
 502                      );
 503                  }).fail(notification.exception);
 504              }
 505          }).fail(notification.exception);
 506          requests[1].done(reloadPage).fail(notification.exception);
 507      };
 508  
 509      /**
 510       * Show a confirm dialogue before deleting a competency.
 511       * @method deleteCompetencyHandler
 512       */
 513      var deleteCompetencyHandler = function() {
 514          var competency = $('[data-region="competencyactions"]').data('competency'),
 515              confirmMessage = 'deletecompetency';
 516  
 517          if (treeModel.hasRule(competency.parentid)) {
 518              confirmMessage = 'deletecompetencyparenthasrule';
 519          }
 520  
 521          str.get_strings([
 522              {key: 'confirm', component: 'moodle'},
 523              {key: confirmMessage, component: 'tool_lp', param: competency.shortname},
 524              {key: 'delete', component: 'moodle'},
 525              {key: 'cancel', component: 'moodle'}
 526          ]).done(function(strings) {
 527              notification.confirm(
 528                  strings[0], // Confirm.
 529                  strings[1], // Delete competency X?
 530                  strings[2], // Delete.
 531                  strings[3], // Cancel.
 532                  doDelete
 533              );
 534          }).fail(notification.exception);
 535      };
 536  
 537      /**
 538       * HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
 539       * @method dragStart
 540       * @param {Event} e
 541       */
 542      var dragStart = function(e) {
 543          e.originalEvent.dataTransfer.setData('text', $(e.target).parent().data('id'));
 544      };
 545  
 546      /**
 547       * HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
 548       * @method allowDrop
 549       * @param {Event} e
 550       */
 551      var allowDrop = function(e) {
 552          e.originalEvent.dataTransfer.dropEffect = 'move';
 553          e.preventDefault();
 554      };
 555  
 556      /**
 557       * HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
 558       * @method dragEnter
 559       * @param {Event} e
 560       */
 561      var dragEnter = function(e) {
 562          e.preventDefault();
 563          $(this).addClass('currentdragtarget');
 564      };
 565  
 566      /**
 567       * HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
 568       * @method dragLeave
 569       * @param {Event} e
 570       */
 571      var dragLeave = function(e) {
 572          e.preventDefault();
 573          $(this).removeClass('currentdragtarget');
 574      };
 575  
 576      /**
 577       * HTML5 implementation of drag/drop (there is an accesible alternative in the menus).
 578       * @method dropOver
 579       * @param {Event} e
 580       */
 581      var dropOver = function(e) {
 582          e.preventDefault();
 583          moveSource = e.originalEvent.dataTransfer.getData('text');
 584          moveTarget = $(e.target).parent().data('id');
 585          $(this).removeClass('currentdragtarget');
 586  
 587          confirmMove();
 588      };
 589  
 590      /**
 591       * Deletes a related competency without confirmation.
 592       *
 593       * @param {Event} e The event that triggered the action.
 594       * @method deleteRelatedHandler
 595       */
 596      var deleteRelatedHandler = function(e) {
 597          e.preventDefault();
 598  
 599          var relatedid = this.id.substr(11);
 600          var competency = $('[data-region="competencyactions"]').data('competency');
 601          var removeRelated = ajax.call([
 602              {methodname: 'core_competency_remove_related_competency',
 603                args: {relatedcompetencyid: relatedid, competencyid: competency.id}},
 604              {methodname: 'tool_lp_data_for_related_competencies_section',
 605                args: {competencyid: competency.id}}
 606          ]);
 607  
 608          removeRelated[1].done(function(context) {
 609              templates.render('tool_lp/related_competencies', context).done(function(html) {
 610                  $('[data-region="relatedcompetencies"]').replaceWith(html);
 611                  updatedRelatedCompetencies();
 612              }).fail(notification.exception);
 613          }).fail(notification.exception);
 614      };
 615  
 616      /**
 617       * Updates the competencies list (with relations) and add listeners.
 618       *
 619       * @method updatedRelatedCompetencies
 620       */
 621      var updatedRelatedCompetencies = function() {
 622  
 623          // Listeners to newly loaded related competencies.
 624          $('[data-action="deleterelation"]').on('click', deleteRelatedHandler);
 625  
 626      };
 627  
 628      /**
 629       * Log the competency viewed event.
 630       *
 631       * @param  {Object} competency The competency.
 632       * @method triggerCompetencyViewedEvent
 633       */
 634      var triggerCompetencyViewedEvent = function(competency) {
 635          if (competency.id !== selectedCompetencyId) {
 636              // Set the selected competency id.
 637              selectedCompetencyId = competency.id;
 638              ajax.call([{
 639                      methodname: 'core_competency_competency_viewed',
 640                      args: {id: competency.id}
 641              }]);
 642          }
 643      };
 644  
 645      /**
 646       * Return the taxonomy constant for a level.
 647       *
 648       * @param  {Number} level The level.
 649       * @return {String}
 650       * @function getTaxonomyAtLevel
 651       */
 652      var getTaxonomyAtLevel = function(level) {
 653          var constant = taxonomiesConstants[level];
 654          if (!constant) {
 655              constant = 'competency';
 656          }
 657          return constant;
 658      };
 659  
 660      /**
 661       * Render the competency summary.
 662       *
 663       * @param  {Object} competency The competency.
 664       */
 665      var renderCompetencySummary = function(competency) {
 666          var promise = $.Deferred().resolve().promise(),
 667              context = {};
 668  
 669          context.competency = competency;
 670          context.showdeleterelatedaction = true;
 671          context.showrelatedcompetencies = true;
 672          context.showrule = false;
 673  
 674          if (competency.ruleoutcome != Outcomes.NONE) {
 675              // Get the outcome and rule name.
 676              promise = Outcomes.getString(competency.ruleoutcome).then(function(str) {
 677                  var name;
 678                  $.each(rulesModules, function(index, modInfo) {
 679                      if (modInfo.type == competency.ruletype) {
 680                          name = modInfo.name;
 681                      }
 682                  });
 683                  return [str, name];
 684              });
 685          }
 686  
 687          promise.then(function(strs) {
 688              if (typeof strs !== 'undefined') {
 689                  context.showrule = true;
 690                  context.rule = {
 691                      outcome: strs[0],
 692                      type: strs[1]
 693                  };
 694              }
 695          }).then(function() {
 696              return templates.render('tool_lp/competency_summary', context).then(function(html) {
 697                  $('[data-region="competencyinfo"]').html(html);
 698                  $('[data-action="deleterelation"]').on('click', deleteRelatedHandler);
 699              });
 700          }).then(function() {
 701              return templates.render('tool_lp/loading', {});
 702          }).then(function(html, js) {
 703              templates.replaceNodeContents('[data-region="relatedcompetencies"]', html, js);
 704          }).done(function() {
 705              ajax.call([{
 706                  methodname: 'tool_lp_data_for_related_competencies_section',
 707                  args: {competencyid: competency.id},
 708                  done: function(context) {
 709                      return templates.render('tool_lp/related_competencies', context).done(function(html, js) {
 710                          $('[data-region="relatedcompetencies"]').replaceWith(html);
 711                          templates.runTemplateJS(js);
 712                          updatedRelatedCompetencies();
 713                      });
 714                  }
 715              }]);
 716          }).fail(notification.exception);
 717      };
 718  
 719      /**
 720       * Return the string "Add <taxonomy>".
 721       *
 722       * @param  {Number} level The level.
 723       * @return {String}
 724       * @function strAddTaxonomy
 725       */
 726      var strAddTaxonomy = function(level) {
 727          return str.get_string('taxonomy_add_' + getTaxonomyAtLevel(level), 'tool_lp');
 728      };
 729  
 730      /**
 731       * Return the string "Selected <taxonomy>".
 732       *
 733       * @param  {Number} level The level.
 734       * @return {String}
 735       * @function strSelectedTaxonomy
 736       */
 737      var strSelectedTaxonomy = function(level) {
 738          return str.get_string('taxonomy_selected_' + getTaxonomyAtLevel(level), 'tool_lp');
 739      };
 740  
 741      /**
 742       * Handler when a node in the aria tree is selected.
 743       * @method selectionChanged
 744       * @param {Event} evt The event that triggered the selection change.
 745       * @param {Object} params The parameters for the event. Contains a list of selected nodes.
 746       * @return {Boolean}
 747       */
 748      var selectionChanged = function(evt, params) {
 749          var node = params.selected,
 750              id = $(node).data('id'),
 751              btn = $('[data-region="competencyactions"] [data-action="add"]'),
 752              actionMenu = $('[data-region="competencyactionsmenu"]'),
 753              selectedTitle = $('[data-region="selected-competency"]'),
 754              level = 0,
 755              sublevel = 1;
 756  
 757          menubar.closeAll();
 758  
 759          if (typeof id === "undefined") {
 760              // Assume this is the root of the tree.
 761              // Here we are only getting the text from the top of the tree, to do it we clone the tree,
 762              // remove all children and then call text on the result.
 763              $('[data-region="competencyinfo"]').html(node.clone().children().remove().end().text());
 764              $('[data-region="competencyactions"]').data('competency', null);
 765              actionMenu.hide();
 766  
 767          } else {
 768              var competency = treeModel.getCompetency(id);
 769  
 770              level = treeModel.getCompetencyLevel(id);
 771              sublevel = level + 1;
 772  
 773              actionMenu.show();
 774              $('[data-region="competencyactions"]').data('competency', competency);
 775              renderCompetencySummary(competency);
 776              // Log Competency viewed event.
 777              triggerCompetencyViewedEvent(competency);
 778          }
 779  
 780          strSelectedTaxonomy(level).then(function(str) {
 781              selectedTitle.text(str);
 782          });
 783  
 784          strAddTaxonomy(sublevel).then(function(str) {
 785              btn.show()
 786                  .find('[data-region="term"]')
 787                  .text(str);
 788          });
 789  
 790          // We handled this event so consume it.
 791          evt.preventDefault();
 792          return false;
 793      };
 794  
 795      /**
 796       * Return the string "Selected <taxonomy>".
 797       *
 798       * @function parseTaxonomies
 799       * @param  {String} taxonomiesstr Comma separated list of taxonomies.
 800       * @return {Array} of level => taxonomystr
 801       */
 802      var parseTaxonomies = function(taxonomiesstr) {
 803          var all = taxonomiesstr.split(',');
 804          all.unshift("");
 805          delete all[0];
 806  
 807          // Note we don't need to fill holes, because other functions check for empty anyway.
 808          return all;
 809      };
 810  
 811      return {
 812          /**
 813           * Initialise this page (attach event handlers etc).
 814           *
 815           * @method init
 816           * @param {Object} model The tree model provides some useful functions for loading and searching competencies.
 817           * @param {Number} pagectxid The page context ID.
 818           * @param {Object} taxonomies Constants indexed by level.
 819           * @param {Object} rulesMods The modules of the rules.
 820           */
 821          init: function(model, pagectxid, taxonomies, rulesMods) {
 822              treeModel = model;
 823              pageContextId = pagectxid;
 824              taxonomiesConstants = parseTaxonomies(taxonomies);
 825              rulesModules = rulesMods;
 826  
 827              $('[data-region="competencyactions"] [data-action="add"]').on('click', addHandler);
 828  
 829              menubar.enhance('.competencyactionsmenu', {
 830                  '[data-action="edit"]': editHandler,
 831                  '[data-action="delete"]': deleteCompetencyHandler,
 832                  '[data-action="move"]': moveHandler,
 833                  '[data-action="moveup"]': moveUpHandler,
 834                  '[data-action="movedown"]': moveDownHandler,
 835                  '[data-action="linkedcourses"]': seeCoursesHandler,
 836                  '[data-action="relatedcompetencies"]': relateCompetenciesHandler.bind(this),
 837                  '[data-action="competencyrules"]': ruleConfigHandler.bind(this)
 838              });
 839              $('[data-region="competencyactionsmenu"]').hide();
 840              $('[data-region="competencyactions"] [data-action="add"]').hide();
 841  
 842              $('[data-region="filtercompetencies"]').on('submit', updateSearchHandler);
 843              // Simple html5 drag drop because we already added an accessible alternative.
 844              var top = $('[data-region="managecompetencies"] [data-enhance="tree"]');
 845              top.on('dragstart', 'li>span', dragStart)
 846                  .on('dragover', 'li>span', allowDrop)
 847                  .on('dragenter', 'li>span', dragEnter)
 848                  .on('dragleave', 'li>span', dragLeave)
 849                  .on('drop', 'li>span', dropOver);
 850  
 851              model.on('selectionchanged', selectionChanged);
 852  
 853              // Prepare the configuration tool.
 854              ruleConfigInstance = new RuleConfig(treeModel, rulesModules);
 855              ruleConfigInstance.on('save', ruleConfigSaveHandler.bind(this));
 856          }
 857      };
 858  });


Generated: Thu Aug 11 10:00:09 2016 Cross-referenced by PHPXref 0.7.1