JSFiddle - React, Tailwind, and code Playground

by Daedalus

HTML

<link rel="stylesheet" href="//maxcdn.bootstrapcdn.com/font-awesome/4.3.0/css/font-awesome.min.css">
<div ng-app="charsheet">
    <div ng-controller="StatListCtrl">
        <form>
            <ul>
                <li ng-repeat="stat in stats" ng-click="checkSel(this,$event)" class="rating"> <span>
                    <input id="{{stat.name}}_{{$id}}" type="radio" ng-repeat-start="dot in num(stat.max, true)" ng-name="stat.name" ng-value="dot" ng-checked="stat.val != 0 && stat.val == dot" /><label for="{{stat.name}}_{{$id}}" class="dot" ng-repeat-end></label>
                  </span>
 <span>{{stat.val}}</span>

                </li>
            </ul>
            <button ng-click="printVals()">submit</button>
        </form>
    </div>
</div>Select dot for stat, click anywhere in red stripe to deselect stat. Check the dev console to see the results after clicking submit.

CSS

li {
    border: 2px solid black;
    background: red;
}
.rating {
    unicode-bidi: bidi-override;
    font-size: 30px;
}
.rating span {
    float: left;
}
.rating span label {
    float: right;
}
.rating span input {
    position: absolute;
    top:-9999px;
    clip:rect(0,0,0,0);
}
.rating span label.dot {
    font-family: FontAwesome;
    font-weight: normal;
    font-style: normal;
    display: inline-block;
}
.rating input:checked ~ label:before {
    content:"\f111";
    padding-right: 1px;
    color: #777;
}

.rating span .dot:before {
    content:"\f1db";
    padding-right: 1px;
    color: #777;
}

JavaScript

var charsheet = angular.module('charsheet', []);

charsheet.controller('StatListCtrl', function ($scope) {
    $scope.num = function (num, reverse) {
        var arr = [],
            iteration = {
                i: (reverse ? num : 1),
                num: num,
            },
            rev = function (iter, rever) {
                if (rever) {
                    if (iter.i <= 1) {
                        return false;
                    } else {
                        iter.i--
                    }
                } else {
                    if (iter.i >= iter.num) {
                        return false;
                    } else {
                        iter.i++;
                    }
                }
                return true;
            },
            cont = true;
        while (cont) {
            arr.push(iteration.i);
            cont = rev(iteration, reverse);
        }
        console.log(arr);
        return arr;
    }
    $scope.stats = [{
        name: "str",
        min: 1,
        max: 5,
        val: 1
    }, {
        name: "dex",
        min: 1,
        max: 4,
        val: 1
    }, {
        name: "sta",
        min: 0,
        max: 5,
        val: 0
    }];
    $scope.checkSel = function (obj, evt) {
        var target = evt.target;
        if (target.value != 0) {
            if (target.checked === true) {
                obj.stat.val = target.value;
            }
        } else {
            obj.stat.val = obj.stat.min;
        }
    };
    $scope.printVals = function () {
        console.log($scope.stats);
    }
});