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);
...