UNPKG

can

Version:

MIT-licensed, client-side, JavaScript framework that makes building rich web applications easy.

231 lines (209 loc) 5.8 kB
<div id="demo"> <div id='out'></div> <script id="app" type="text/stache"> <my-mmy> <select {($value)}="makeIdString" {{#makes.isPending}}disabled{{/makes.isPending}}> {{#if makes.isPending}} <option value=''>Loading...</option> {{else}} {{^makeId}} <option value=''>Select a Make</option> {{/makeId}} {{#each makes.value}} <option value="{{id}}">{{name}}</option> {{/each}} {{/if}} </select> {{#if modelsPromise}} {{#if models}} <select {($value)}="modelIdString"> {{^modelId}} <option value=''>Select a Model</option> {{/modelId}} {{#each models}} <option value="{{id}}">{{name}}</option> {{/each}} </select> {{else}} <select disabled><option>Loading Models</option></select> {{/if}} {{else}} <select disabled><option>Models</option></select> {{/if}} {{#if years}} <select {($value)}="yearString"> {{^year}} <option value=''>Select a Year</option> {{/year}} {{#each years}} <option value="{{.}}">{{.}}</option> {{/each}} </select> {{else}} <select disabled><option>Years</option></select> {{/if}} <div> {{#each vehicles}} <h2>{{name}}</h2> <img src="{{thumb}}" width="200px"/> {{/each}} </div> </my-mmy> </script> </div> <script> DEMO_HTML = document.getElementById("demo").innerHTML </script> <script src="../../../../node_modules/steal/steal.js" main="@empty"></script> <script id="demo-source"> steal("can","can/map/define","can/util/fixture","can/view/stache", function(){ can.fixture.delay = 1200; can.fixture({ "/makes" : can.fixture.store([ {id: 1, name: "Ford"}, {id: 2, name: "Nissan"} ]).findAll, "/models": can.fixture.store([ {id: 1, makeId: 1, name: "Mustang", years: [2013, 2014]}, {id: 2, makeId: 1, name: "Focus", years: [2013, 2014]}, {id: 3, makeId: 2, name: "Altima", years: [2013, 2014]}, {id: 4, makeId: 2, name: "Leaf", years: [2013, 2014]}, ]).findAll, "/vehicles": can.fixture.store([ {id: 1, modelId: 1, year: 2013, name: "2013 Mustang", thumb: "http://mustangsdaily.com/blog/wp-content/uploads/2012/07/01-2013-ford-mustang-gt-review-585x388.jpg"}, {id: 2, modelId: 1, year: 2014, name: "2014 Mustang", thumb: "http://mustangsdaily.com/blog/wp-content/uploads/2013/03/2014-roush-mustang.jpg"}, {id: 3, modelId: 2, year: 2013, name: "2013 Focus", thumb: "http://images.newcars.com/images/car-pictures/original/2013-Ford-Focus-Sedan-S-4dr-Sedan-Exterior.png"}, {id: 4, modelId: 2, year: 2014, name: "2014 Focus", thumb: "http://ipinvite.iperceptions.com/Invitations/survey705/images_V2/top4.jpg"}, {id: 5, modelId: 3, year: 2013, name: "2013 Altima", thumb: "http://www.blogcdn.com/www.autoblog.com/media/2012/04/04-2013-nissan-altima-1333416664.jpg"}, {id: 6, modelId: 3, year: 2014, name: "2014 Altima", thumb: "http://www.blogcdn.com/www.autoblog.com/media/2012/04/01-2013-nissan-altima-ny.jpg"}, {id: 7, modelId: 4, year: 2013, name: "2013 Leaf", thumb: "http://www.blogcdn.com/www.autoblog.com/media/2012/04/01-2013-nissan-altima-ny.jpg"}, {id: 8, modelId: 4, year: 2014, name: "2014 Leaf", thumb: "http://images.thecarconnection.com/med/2013-nissan-leaf_100414473_m.jpg"}, ],{year: 'eqeq', name: "i"}).findAll }); var CarMake = can.Model.extend({ findAll: "/makes" },{}); var CarModel = can.Model.extend({ findAll: "/models" },{}); var Vehicle = can.Model.extend({ findAll: "/vehicles" },{}); var project = new can.Map({ progress: 1 }); var selectStringForNumberProp = function(prop) { return { get: function(){ var value = this.attr(prop); if(typeof value === "number") { return ""+value; } else { return ""; } }, set: function(newVal){ var toNum = +newVal; console.log("set", prop, newVal); if(toNum !== toNum) { // NaN this.removeAttr(prop); } else { this.attr(prop, toNum); } } }; }; var MMYViewModel = can.Map.extend({ define:{ makes: { value: function(){ return CarMake.findAll({}); }, serialize: false }, makeId: { type: "number", remove: function(){ this.removeAttr("modelId"); }, set: function(){ this.removeAttr("modelId"); } }, makeIdString: selectStringForNumberProp("makeId"), modelsPromise: { get: function(){ var makeId = this.attr("makeId"); if( makeId ) { return CarModel.findAll({makeId: makeId}); } } }, models: { get: function(lastSet, resolve){ var promise = this.attr("modelsPromise"); if(promise) { promise.then(function(models){ console.log("models", models.attr()); resolve(models); }); return null; } } }, model: { get: function(){ var models = this.attr("models"), modelId = this.attr("modelId"); if(models && models.attr('length') && modelId) { var matched = models.filter(function(model){ return modelId == model.attr("id"); }); return matched[0]; } } }, modelId: { type: "number", remove: function(){ this.removeAttr("year"); }, set: function(){ this.removeAttr("year"); } }, modelIdString: selectStringForNumberProp("modelId"), years: { get: function(){ var model = this.attr("model"); return model && model.attr("years"); } }, year: { type: "number" }, yearString: selectStringForNumberProp("year"), vehicles: { get: function(){ var year = this.attr("year"), modelId = this.attr("modelId"); if( modelId !== undefined && year) { return new Vehicle.List({modelId: modelId, year: year}); } } } } }); var mmy = new MMYViewModel(); can.route.map(mmy); can.route.ready(); can.Component.extend({ tag: "my-mmy", scope: mmy }); $("#out").html( can.view("app",{}) ); }); </script>