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 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>
        {{#each tiles}}{{>tile_template}}{{/each}}
    </ul>
</script>
    
<script id="page_template" type="text/mustache">
    <div {{control wsi.TilesControl}}></div>
</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%}
ul li {display:inline-block}

JavaScript

(function() {
    if(window.history && history.pushState) {

        var getPath = function() {
            return location.pathname + location.search;
        };

        // popstate only fires on back/forward.
        // To detect when someone calls push/replaceState, we need to wrap each method.
        can.each(['pushState','replaceState'],function(method) {
            var orig = history[method];
            history[method] = function(state) {
                var result = orig.apply(history, arguments);
                can.route.history.attr('path',getPath());
                can.route.history.attr('type',method);
                return result;
            };
        });
        // Bind to popstate for back/forward
        can.bind.call(window, 'popstate', function() {
            can.route.history.attr('path',getPath());
            can.route.history.attr('type','popState');
        });

        var param = can.route.param,
            paramsMatcher = /^\?(?:[^=]+=[^&]*&)*[^=]+=[^&]*/;
        can.extend(can.route, {
            history: new can.Observe({path:getPath()}),
            _paramsMatcher: paramsMatcher,
            _querySeparator: '?',
            _setup: function() {
                // intercept routable links
                can.$('body').on('click', 'a', function(e) {
                    if(!e.isDefaultPrevented()) {
                        // Fix for ie showing blank host, but blank host means current host.
                        if(!this.host) {
                          this.host = window.location.host;
                        }
                        // HTML5 pushstate requires host to be the same. Don't prevent default for other hosts.
                        if(can.route.updateWith(this.pathname+this.search) && window.location.host == this.host) {
                            e.preventDefault();
                        }
                    }
                });
                can.route.history.bind('path',can.route.setState);
       ...