shop model

by rwaldin

HTML

<script src="http://canjs.com/release/latest/can.zepto.js"></script>
<script src="http://canjs.com/release/latest/can.view.mustache.js"></script>
<script src="http://canjs.com/release/latest/can.construct.super.js"></script>
<script src="http://canjs.com/release/latest/can.observe.attributes.js"></script>
<div class="header">
    <h1>Testing CanJS + Zepto</h1>
</div>

<!-- YOUR CODE HERE -->
<div id="pageContainer"></div>

<!-- PUT ANY TEMPLATES YOU NEED HERE -->
<script id="price_range_template" type="text/mustache">
    <span class="price-range">{{currencySymbol}}{{lowPrice}} - {{currencySymbol}}{{highPrice}}</span>
</script>

<script id="tile_template" type="text/mustache">
    <li class='tile' id="tile_{{id}}"><img src="{{thumbnailUrl}}"/><div>{{name}}</div><div>{{#with priceRange}}{{>price_range_template}}{{/with}}</li>
</script>

<script id="tiles_template" type="text/mustache">
    <ul class='tiles-grid'> {{#each tiles}}{{>tile_template}}{{/each}}</u>
</script>
    
<script id="page_template" type="text/mustache">
    {{control 'wsi.TilesControl' tiles=tiles view='tiles_template'}}
        <div id="{{controlId}}"/>
    {{/control}}
</script>

CSS

.header {
    background: #E1E3E1;
    padding: 10px 0;
    border-bottom: 1px solid #B5B6B5;
    margin-bottom: 15px;
}
h1 {
    font-size: 24px;
    font-weight: bold;
}
.tile {display:block; float:left; text-align:center;}

JavaScript

(function() {
    function addNames(namespace, context) {
        for(var prop in context) {
            if(prop.match(/^[A-Z][^A-Z]/) && context.hasOwnProperty(prop)) {
                var constructor = context[prop];
                if(constructor === constructor.constructor && !constructor.fullName) {
                    can.extend(constructor, {
                        fullName: namespace + '.' + prop,
                        shortName: prop,
                        namespace: namespace
                    });
                    addNames(constructor.namespace, constructor);
                }
            }
        }
    }
    addNames('can', can);
    // the can.Observe.attributes plugin doesn't make declared attributes inheritable... this patch fixes that
    var oldObserveSetup = can.Observe.setup;
    can.Observe.setup = function(superConstructor, stat, proto) {
        oldObserveSetup.apply(this, arguments);
        this.attributes = can.extend({}, superConstructor.attributes || {}, this.attributes || {});
    };
    var oldConstructSetup = can.Construct.setup;
    can.Construct.setup = function(superConstructor, fullName, statics, protos) {
        oldConstructSetup.apply(this, arguments);
        this.baseConstructor = superConstructor;
    };
}());

(function() {
    // bidirectional live binding example
    var Value = can.Control({
        init: function() {this.set();},

        set: function() {
            this.element.val(this.options.value());
        },
        "{value} change": "set",
        "change": function(){
            this.options.value(parseInt(this.element.val(), 10));
        }
    });

    can.Mustache.registerHelper('value', function(value) {
        return function(el) {
            new Value(el, {value: value});
        };
    });
}());

(function(undefined) {
    can.Observe("wsi.PriceRange", {
        attributes: {
            currencySymbol: 'default',
            lowPrice: 'default',
            highPrice: 'default'
       ...