Slider input block with AngularJS

by Ivan Gerasimenko

HTML

<link rel="stylesheet" href="http://prajwalkman.github.io/angular-slider/angular-slider/angular-slider.css">
<script src="http://prajwalkman.github.io/angular-slider/angular-slider/angular-slider.js"></script>
<link rel="stylesheet" href="http://netdna.bootstrapcdn.com/twitter-bootstrap/2.3.0/css/bootstrap-combined.min.css">
<div ng-app="myApp" ng-controller="MyCtrl">
    <div class="control-block" ng-repeat="item in items">
        <span>{{ item.name }}</span>
        <input type="range" step="0.01" ng-model="item.percent" ng-change="item.reassignPercentage()">
            <input type="number" ng-model="item.percent" ng-change="item.reassignPercentage()" min="0" max="100" ng-pattern="/^\d{1,3}([\.,](\d{1,2})?)?$/">
    </div>
    <div class="trace-block" ng-repeat="item in items">
        <span>{{ item.name }} </span>
        <span>{{ item.percent }}%</span>
    </div>
</div>

CSS

input[type=number]{
    width: 70px;
    margin-top: 10px;
    margin-left: 5px;
}
.control-block > span {
    width: 60px;
    display: inline-block;
}

.trace-block > span {
    width: 60px;
    display: inline-block;
}
input.ng-invalid-pattern {
    border-color: rgba(236, 82, 119, 0.8);
outline: 0;
outline: thin dotted \9;
-webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(236,82,119,.6);
-moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(236,82,119,.6);
box-shadow: inset 0 1px 1px rgba(0,0,0,.075), 0 0 8px rgba(236,82,119,.6);
}

JavaScript

angular.module('myApp', [])
.controller('MyCtrl', function($scope, Item) {
    Item.getAll().then(function(items){
        $scope.items = items;
    });
})
.value('ItemsSet', [
    {name: 'Item 1', percent: 0},
    {name: 'Item 2', percent: 0},
    {name: 'Item 3', percent: 0},
    {name: 'Item 4', percent: 0}
])
.factory('Item', ['$q', 'ItemsSet', function($q, ItemsSet){
    var cache = {};

    var Item = function(data) {
        angular.extend(this, data);
    };

    function initObject(data) {
        if(cache[data.name]) {
            angular.extend(cache[data.name], data);
        } else {
            cache[data.name] = new Item(data);
        }
        return cache[data.name];
    }

    Item.getAll = function() {
        console.log("itemset", ItemsSet);
        angular.forEach(ItemsSet, function(item) {
            return initObject(item);
        });
                
        return $q.when(cache);
    };

    Item.prototype.reassignPercentage = function() {
        this.percent = parseFloat(Number(this.percent).toFixed(2));
        
        var curItem = this;
        var itemsCount = ItemsSet.length;
        var percentSumNotChanged = 0;
        var lowestItem = {percent: 101};
        var highestItem = {percent: -1};
        for(i=0; i<itemsCount; i++) {
            if(cache[ItemsSet[i].name].name != curItem.name) {
                percentSumNotChanged += 
                    parseFloat(cache[ItemsSet[i].name].percent);
                
                if(parseFloat(cache[ItemsSet[i].name].percent)
                   > highestItem.percent) {
                    highestItem = cache[ItemsSet[i].name];
                }
                
                if(parseFloat(cache[ItemsSet[i].name].percent)
                   < lowestItem.percent) {
                    lowestItem = cache[ItemsSet[i].name];
                }
            }               
        }
        
        var delta = 100 - percentSumNotChanged - this.percent;
        delta =...