Responsive scale elements

using angular & jquery. fully customizable. responsive.

by Ercan Cicek

HTML

<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.6/angular.min.js"></script>
<!-- RESPONSIVE SCALE ELEMENTS -->
<!-- make sure the external resources - angular and jquery - are available -->
<!-- fully customizable -->
<body ng-app="boxApp" ng-controller="boxCtrl" class="flex-display flex-row flex-center flex-spaceB">

  <div class="ratingArea flex-display flex-row flex-spaceB" ng-repeat="i in [0,1]">
    <a href="#" class="flex-display flex-column flex-spaceB" ng-repeat="box in task.boxes" ng-click="boxClicked(box.id);" 
    ng-if="i === 0 ? $index < (task.boxes.length / 2) : $index >= (task.boxes.length / 2)">
      <div ng-repeat="field in box.default track by $index" 
      ng-class="box.active ? (field === 1 ? (task.boxesActive ? 'field-active' : 'field-normal') : 'field-disabled') : (field === 1 ? 'field-normal' : 'field-disabled')"></div>
    </a>
  </div>

</body>

CSS

html, body {
  width: 100%;
  position: relative;
}

html {
  height: 100%;
}

body {
  height: 15%;
}

.ratingArea:first-child {
    margin-right: 5px;
}

.ratingArea {
    width: 50%;
    height: 100%;
    margin: 10px 10px 10px 5px;
}

.ratingArea > a {
    width: 32%;
    height: 100%;
    cursor: pointer;
    -webkit-box-shadow: none !important;
    box-shadow: none !important;
}

.ratingArea > a > div {
    height: 32%;
    width: 100%;
}

.field-active {
    background-color: #e17800 !important;
}

.field-normal {
    background-color: #000;
}

.field-disabled {
    background-color: transparent !important;
}

.field-inactive {
    background-color: #E0E0E0;
    opacity: .6;
}

/* --- flex classes --- */
.flex-display {
    display: -webkit-box !important;
    display: -ms-flexbox !important;
    display: -moz-flex !important;
    display: -webkit-flex !important;
    display: flex !important;
}

.flex-column {
    -webkit-box-orient: vertical;
    -moz-box-orient: vertical;
    -webkit-flex-direction: column;
    -ms-flex-direction: column;
    flex-direction: column;
}

.flex-row {
    -webkit-box-orient: horizontal;
    -ms-flex-direction: row;
    -moz-flex-direction: row;
    -webkit-flex-direction: row;
    flex-direction: row;
}

.flex-spaceB {
    -webkit-box-pack: justify;
    -moz-box-pack: justify;
    -webkit-justify-content: space-between;
    -ms-flex-pack: justify;
    justify-content: space-between;
}

JavaScript

// --- angular app
let app = angular.module('boxApp', []);
app.controller('boxCtrl', ['$scope', '$timeout', function($scope, $timeout) {

	// --- declared object to bind with angular elements
  $scope.task = {
  // --- box defaults are easily customizable
    boxes: [
      {
        id: 1, box: 1, value: 3, default: [1, 1, 1], active: true
      }, {
        id: 2, box: 1, value: 2, default: [0, 1, 1], active: true
      }, {
        id: 3, box: 1, value: 1, default: [0, 0, 1], active: true
      }, {
        id: 4, box: 2, value: 1, default: [0, 0, 1], active: true
      }, {
        id: 5, box: 2, value: 2, default: [0, 1, 1], active: true
      }, {
        id: 6, box: 2, value: 3, default: [1, 1, 1], active: true
      }
    ],
    boxesActive: false
  };

  $scope.boxClicked = function(boxId) {
  	// --- timeout 0 to trigger soft scope apply in angular
    $timeout(function () {
      let clickedBox = $scope.task.boxes.find(function(bx) { return bx.id === boxId; });
      $scope.task.boxes.forEach(function (box) { 
        box.active = (box.box === clickedBox.box && box.value <= clickedBox.value); 
      });
      $scope.task.boxesActive = true;
    });
  };

}]);