commands/ToggleCommandGroup.js

/**
 * @copyright 2016 Tridium, Inc. All Rights Reserved.
 * @author Vikram Nagulan
 */

/**
 * @module bajaux/commands/ToggleCommandGroup
 */
define([
  'underscore',
  'bajaux/commands/CommandGroup',
  'bajaux/commands/ToggleCommand' ], function (
   _,
   CommandGroup,
   ToggleCommand) {

  'use strict';

  /**
   * Unselect other commands when this is invoked.
   *
   * @private
   * @param {module:bajaux/commands/ToggleCommandGroup} cmdGrp - this group reference
   * @param {Number} id - The unique id representing this command, see Command.getId()
   */
  function toggleOthers(cmdGrp, id) {
    var toReset = _.filter(cmdGrp.getChildren(), function (cmd) {
      return (cmd.constructor === ToggleCommand) && (id !== cmd.getId());
    });
    _.map(toReset, function (c) {
      c.setSelected(false);
    });
  }

  /**
   * ToggleCommandGroup is a special CommandGroup that behaves like a radio button group.
   *
   * @class
   * @alias module:bajaux/commands/ToggleCommandGroup
   * @extends module:bajaux/commands/CommandGroup
   *
   * @param {object} params
   * @param {function} params.onChange - provide a callback function that can work with the selected value
   * @param {Array} params.commands - An array of objects, each of which will pass through to making a
   * ToggleCommand. See {@link module:bajaux/commands/Command} for all acceptable parameters.
   * Pass an optional "value" parameter to a command configuration object to associate a value with it.
   *
   * @example
   * new ToggleCommandGroup({
   *   commands: [
   *     {
   *       module: "mymodule",
   *       lex: "mycommand1",
   *       value: 0
   *     },
   *     {
   *       module: "mymodule",
   *       lex: "mycommand2",
   *       value: 1
   *     },
   *     {
   *       module: "mymodule",
   *       lex: "mycommand3",
   *       value: 2
   *     }
   *   ],
   *   onChange: function (value) {
   *     // receives the values specified above.
   *     switch (value) {
   *       case 0:
   *       case 1:
   *       case 2:
   *     }
   *   }
   * });
   * @example
   * <caption>Use a flat style for your toggle button group.</caption>
   * var buttonGroup = new CommandButtonGroup();
   * return buttonGroup.initialize(dom, { toggleGroup: true })
   *   .then(function () {
   *     return buttonGroup.load(toggleCommandGroup);
   *   });
   */
  var ToggleCommandGroup = function ToggleCommandGroup(params) {
    var that = this;
    CommandGroup.apply(that, params.commands || arguments);
    that.onChange = params.onChange;
    if (params && params.commands) {
      _.each(params.commands, function (cmd) {
        //Override Command.func
        cmd.func = function () {
          var args = Array.prototype.slice.call(arguments);
          this.setSelected(true);
          toggleOthers(that, this.getId());
          //Callback onChange passing in the selected value
          if (that.onChange) {
            return that.onChange.apply(that, [ this.$value ].concat(args));
          }
        };
        var c = new ToggleCommand(cmd);
        //If an optional value is passed set it
        c.$value = cmd.value;
        that.add(c);
      });
    }
  };

  ToggleCommandGroup.prototype = Object.create(CommandGroup.prototype);
  ToggleCommandGroup.prototype.constructor = ToggleCommandGroup;

  /**
   * Get the selected command
   * @return {module:bajaux/commands/ToggleCommand} The selected ToggleCommand
   */
  ToggleCommandGroup.prototype.getSelected = function () {
    return _.find(this.getChildren(), function (cmd) {
      return cmd.isSelected();
    });
  };

  /**
   * Get the selected value if available
   * @return {any} If a 'value' parameter is set it will be returned
   */
  ToggleCommandGroup.prototype.getSelectedValue = function () {
    return this.getSelected().$value;
  };

  return ToggleCommandGroup;
});