CanJS Zepto Template

Includes Zepto, CanJS and all of its plugins. Use it as a starting point when you want to demo something.

by rwaldin

HTML

<script src="http://canjs.us/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="putTileWidgetHere"></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">
    <p id="msg">ID: {{tile.id}}</p>
    <p><a href="#">Click me for a random ID</a></p>
    Enter a new ID: <input type="number" id="input" {{value tile.id}}/>
    <dl>
        <dt>name</dt><dd>{{tile.name}}</dd>
        <dt>thumbnailUrl</dt><dd>{{tile.thumbnailUrl}}</dd>
        <dt>priceRange</dt><dd>{{#tile.priceRange}}{{>price_range_template}}{{/tile.priceRange}}</dd>
    </dl>
</script>

CSS

.header {
    background: #E1E3E1;
    padding: 10px 0;
    border-bottom: 1px solid #B5B6B5;
    margin-bottom: 15px;
}
h1 {
    font-size: 24px;
    font-weight: bold;
}
p { 
    margin: 10px 0;
}
dt {float: left; margin-right: 10px}
input {width: 6em; font-size: 80%}

JavaScript

(function() {
        // can.Observe.attributes neglected to make declared attributes inheritable... this patch fixes that
        var oldSetup = can.Observe.setup;
        can.Observe.setup = function(superClass, stat, proto) {
            oldSetup.apply(this, arguments);
            this.attributes = can.extend({}, superClass.attributes || {}, this.attributes || {});
        };
    }());

    // two way binder for inputs 
    var Value = can.Control({
            init: function() {
                this.set();
            },
            "{value} change": "set",
            set: function(){
                this.element.val(this.options.value());
            },
            "change": function(){
                this.options.value(parseInt(this.element.val(), 10));
            }
        });

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

    var PriceRange = can.Observe("PriceRange", {
            attributes: {
                currencySymbol: 'default',
                lowPrice: 'default',
                highPrice: 'default'
            }
        }, {}),
        
        AssortmentItem = can.Observe('AssortmentItem', {
            attributes: {
                id: 'number',
                name: 'string'
            }
        }, {}),

        AssortmentItemTile = AssortmentItem('AssortmentItemTile', {
            attributes: {
                thumbnailUrl: 'default'
            }
        }, {}),

        CategoryItemTile = AssortmentItemTile('CategoryItemTile', {
            attributes: {
                containerPage: 'default',
                categoryPage: 'default'
            }
        }, {}),

        SupercategoryTile = CategoryItemTile('SupercategoryTile'),
        CategoryTile = CategoryItemTile('CategoryTile'),
        SubcategoryTile = CategoryItemTile('SubcategoryTile'),

        GroupTile = AssortmentItemTile('GroupTile', {
            attributes:...