Ember Color Picker Component

by Kerrick

HTML

<script src="http://cdnjs.cloudflare.com/ajax/libs/handlebars.js/1.1.2/handlebars.min.js"></script>
<script src="http://builds.emberjs.com/tags/v1.2.2/ember.js"></script>
<script src="http://builds.emberjs.com/beta/ember-data.js"></script>
<script type="text/x-handlebars" id="index">
    {{color-picker hex='ff8800'}}
</script>
<script type="text/x-handlebars" id="components/color-picker">
    Red: {{input type='number' value=red maxlength='3' min='0' max='255'}}<br />
    Green: {{input type='number' value=green maxlength='3' min='0' max='255'}}<br />
    Blue: {{input type='number' value=blue min='0' maxlength='3' max='255'}}<br />
    Color: #{{input type='text' maxlength="6" pattern="([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})" value=hex}}
    <div class="colorPreview" {{bind-attr style=colorStyle}}></div>
</script>

CSS

body {
    padding: 1em;
}
.colorPreview {
    width: 3em;
    height: 3em;
    border: 1px solid black;
}

JavaScript

App = Ember.Application.create();
(function() {
    var decimalComputed = function(index) {
        return Ember.computed('hex', function(key, value) {
            if (arguments.length > 1) {
                // setter
                var hex = this.get('hex');
                var pairs = [0, 2, 4].map(function(start) { return hex.substr(start, 2); });
                pairs[index] = this.decimalToHex(parseInt(value, 10));
                this.set('hex', pairs.join(''));
            }
            
            // getter
            return this.hexToDecimal(this.get('hex').substr(index * 2, 2));
        });
    };
    App.ColorPickerComponent = Ember.Component.extend({
        hex: '000000',
        red: decimalComputed(0),
        green: decimalComputed(1),
        blue: decimalComputed(2),
        colorStyle: Ember.computed('hex', function() {
            return 'background-color: #' + this.get('hex');
        }),
        hexToDecimal: function(hexString) {
            return parseInt(hexString, 16);
        },
        decimalToHex: function(int) {
            return this.pad(int.toString(16), '0', 2);
        },
        pad: function(string, char, length) {
            if (string.length < length) {
                string = char + string;
                return this.pad(string);
            }
            return string;
        }
    });
)();
decimalComputed; // undefined
App.ColorPickerComponent // Class
Ember.TextField.reopen({
  attributeBindings: ['size', 'maxlength', 'minlength', 'min', 'max', 'step', 'pattern']
})