daveskylark
daveskylark

Reputation: 2794

Use one md-switch to toggle a group of other md-switchs in HTML/JS

I am wanting to be able to toggle and untoggle entire group sections. When the group section is toggled off, I want the sections in the group to toggle off as well or be disabled. If the group section is toggled on, I want the sections toggled on as well or enabled. I added ng-change to the group toggle with the function toggleLayerGroup. I also have a forEach inside the function that goes through the feeds in the group. I am just not sure what to add to turn off or on the feeds in the group.

Controller

This is where the feeds are loaded up.

// -- load feeds
  if (Service.currentUser.feeds) {
    var feeds = Service.currentUserOrg.feeds;
    angular.forEach(feeds, function(feed, index) {
      var lg = $scope.layerGroups[feed.category];
      if(lg) {
        lg.feeds[feed.id] = feed;
        lg.feeds[feed.id].layerState = Service.currentUser.mapState.visibleLayers.indexOf(feed.id) >= 0;
        if (lg.feeds[feed.id].layerState) {
          lg.state = true;
        }
      }
    });
  }

This is where the switches are hit.

$scope.layerState = false;
$scope.layerGroup = false;

$scope.toggleLayer = function (layerState, feed) {
  if (layerState) {
    subscribeFeed(feed);

    if (Service.currentUser.mapState.visibleLayers.indexOf(feed.id) < 0) {
      Service.currentUser.mapState.visibleLayers.push(feed.id);
      $scope.saveState();
    }
  }
  else {
    unsubscribeFeed(feed);

    var index = Service.currentUser.mapState.visibleLayers.indexOf(feed.id);
    if (index >= 0) {
      Service.currentUser.mapState.visibleLayers.splice(index, 1);
      $scope.saveState();
    }
  }
};

$scope.toggleLayerGroup = function (layerGroupState, layerGroup) {
  if (!layerGroupState) {
    angular.forEach(layerGroup.feeds, function (feed, index) {
      subscribeFeed(feed);
      $scope.saveState();
    });
  }
  else {
    angular.forEach(layerGroup.feeds, function (feed, index) {
      unsubscribeFeed(feed);
      $scope.saveState();
    });
  }
};

function subscribeFeed(feed) {
  switch (feed.category) {
    case 'people':
    case 'assets':
      feed._markerColl = {};
      feed.processEntity = processEntity;
      feed.clearFeed = clearFeed;
      break;
    case 'places':
      feed._placeColl = {};
      feed.processEntity = processEntity;
      feed.clearFeed = clearFeed;
      break;
  }
  feed.icons = Service.currentUser.feedIcons;
  feed.off = NextService.on(feed.id, function (data) {
    feed.processEntity(data);
  });

function unsubscribeFeed(feed) {
  feed.off();
  delete feed.off;
  NextService.emit('unsubscribe', {id: feed.id});
  feed.clearFeed();
}

Upvotes: 1

Views: 1299

Answers (2)

daveskylark
daveskylark

Reputation: 2794

I finally got this to work properly. These are the changes I made.

HTML

<!--LAYER TOGGLE SWITCH-->
        <md-switch class="md-primary" ng-model="layerGroup.state" ng-change="toggleLayerGroup(layerGroup)" aria-label="{{layerGroup.displayName}} Toggle Switch"></md-switch>

<!--LAYER FEEDS-->
      <div  ng-repeat="feed in layerGroup.feeds" layout="row" layout-align="start center" style="padding: 0 16px;">
        <!--FEED NAME-->
        <p flex class="m2" style="color: #FFFFFF;" ng-style="{ 'opacity' : layerGroup.state ? '1' : '.3' }">{{feed.name}}</p>
        <!--FEED SWITCH-->
        <md-switch class="md-primary" ng-model="feed.layerState" ng-disabled="!layerGroup.state" ng-change="toggleLayer(feed)" aria-label="{{feed.name}} Toggle Switch"></md-switch>
      </div>

I added ng-style to show when the feeds are disabled. And ng-disabled to disable the switch when the layerGroupState is false.

Controller

// -- load feeds
  if (EcosystemService.currentUserOrg.feeds) {
    var feeds = EcosystemService.currentUserOrg.feeds;
    angular.forEach(feeds, function(feed, index) {
      var lg = $scope.layerGroups[feed.category];
      if(lg) {
        lg.feeds[feed.id] = feed;
        lg.feeds[feed.id].layerState = EcosystemService.currentUser.mapState.visibleLayers.indexOf(feed.id) >= 0;
        if (lg.feeds[feed.id].layerState) {
          lg.state = true;
        }
      }
    });
  }

$scope.toggleLayerGroup = function (layerGroup) {
  if (layerGroup.state) {
    angular.forEach(layerGroup.feeds, function (feed) {
      subscribeFeed(feed);

      if (EcosystemService.currentUser.mapState.visibleLayers.indexOf(feed.id) < 0) {
        EcosystemService.currentUser.mapState.visibleLayers.push(feed.id);
        $scope.saveState();
      }
      feed.layerState = true;
    });
  }
  else {
    angular.forEach(layerGroup.feeds, function (feed) {
      unsubscribeFeed(feed);

      var ndex = EcosystemService.currentUser.mapState.visibleLayers.indexOf(feed.id);
      if (ndex >= 0) {
        EcosystemService.currentUser.mapState.visibleLayers.splice(ndex, 1);
        $scope.saveState();
      }
      feed.layerState = false;
    });
  }
};

I added code to the place where the feeds are loaded and added code in toggleLayerGroup that will change the layerState dependending on the value of the layerGroup.

Upvotes: 1

Vikram Tiwari
Vikram Tiwari

Reputation: 3905

Your toggleLayerGroup function should run a loop over layerGroup.feeds which will have the toggle's state info in them. For each value of layerGroup.feed it should pass it to toggleLayer function which will manage the subscription and view states.

While you are doing this, just find the state of toggleLayerGroup and pass it to each feed value for a group controlled view behavior.

Upvotes: 0

Related Questions