UNPKG

can

Version:

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

317 lines (293 loc) 6.13 kB
<make-model-year id="out"></make-model-year> <script src="../../node_modules/steal/steal.js" dev-bundle main='@empty'> import { CanMap, Component, DefineMap, DefineList, QueryLogic, fixture, restModel, route } from "can"; import "can-map-define"; fixture.delay = 1200; const eqeq = (a, b) => { if (a && b) { return a == b; } }; fixture({ "/makes": fixture.store([{ id: 1, name: "Ford" }, { id: 2, name: "Nissan" }]).getListData, "/models": 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] }], { makeId: eqeq }).getListData, "/vehicles": 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, modelId: eqeq }).getListData }); const CarMake = DefineMap.extend({ seal: false }, { id: { type: "string", identity: true } }); CarMake.queryLogic = new QueryLogic(CarMake); const CarModel = DefineMap.extend({ seal: false }, { id: { type: "string", identity: true } }); CarModel.queryLogic = new QueryLogic(CarModel); const Vehicle = DefineMap.extend({ seal: false }, { id: { type: "string", identity: true } }); Vehicle.queryLogic = new QueryLogic(Vehicle); CarMake.List = DefineList.extend({ "#": CarMake }); CarModel.List = DefineList.extend({ "#": CarModel }); Vehicle.List = DefineList.extend({ "#": Vehicle }); CarMake.connection = restModel({ Map: CarMake, List: CarMake.List, url: "/makes/{id}" }); CarModel.connection = restModel({ Map: CarModel, List: CarModel.List, url: "/models/{id}" }); Vehicle.connection = restModel({ Map: Vehicle, List: Vehicle.List, url: "/vehicles/{id}" }); const MMYViewModel = CanMap.extend({ define: { makes: { get() { return CarMake.getList({}); }, serialize: false }, makeId: { type: "number", remove() { this.removeAttr("modelId"); }, set(newValue) { if (newValue !== this.makeId) { this.removeAttr("modelId"); } return newValue; } }, modelsPromise: { get() { let makeId = this.attr("makeId"); if (makeId) { return CarModel.getList({ filter: { makeId: makeId } }); } } }, models: { get: function(lastSet, resolve) { let promise = this.attr("modelsPromise"); if (promise) { promise.then(function(models) { resolve(models); }); return null; } } }, model: { get() { let models = this.attr("models"), modelId = this.attr("modelId"); if (models && models.length && modelId) { var matched = models.filter(function(model) { return modelId == model.id; }); return matched[0]; } } }, modelId: { type: "number", remove() { this.removeAttr("year"); }, set(newValue) { if (newValue !== this.modelId) { this.removeAttr("year"); } return newValue; } }, years: { get() { let model = this.attr("model"); return model && model.years; } }, year: { type: "number" }, vehicles: { get() { let year = this.attr("year"), modelId = this.attr("modelId"); if (modelId !== undefined && year) { return new Vehicle.getList({ filter: { modelId: modelId, year: year } }); } } } } }); Component.extend({ tag: "make-model-year", view: ` {{# if(this.makes.isResolved) }} <select value:bind="string-to-any(~makeId)"> {{^makeId}} <option value="undefined">Select a Make</option> {{/makeId}} {{# for (carMake of makes.value)}} <option value="{{carMake.id}}">{{carMake.name}}</option> {{/ for }} </select> {{else}} <select disabled> <option>Loading...</option> </select> {{/ if }} {{# if(this.modelsPromise) }} {{# if(models) }} <select value:bind="string-to-any(~modelId)"> {{^ modelId }} <option value="undefined">Select a Model</option> {{/ modelId }} {{# for (carModel of models)}} <option value="{{carModel.id}}">{{carModel.name}}</option> {{/for}} </select> {{ else }} <select disabled> <option>Loading Models</option> </select> {{/ if }} {{ else }} <select disabled> <option>Models</option> </select> {{/if}} {{# if(years) }} <select value:bind="string-to-any(~year)"> {{^ year}} <option value="undefined">Select a Year</option> {{/year}} {{# for (year of years)}} <option value="{{year}}">{{year}}</option> {{/ for }} </select> {{ else }} <select disabled> <option>Years</option> </select> {{/ if }} <div> {{# for (vehicle of this.vehicles.value) }} <h2>{{vehicle.name}}</h2> <img src="{{vehicle.thumb}}" width="200px" /> {{/ for }} </div> `, ViewModel: MMYViewModel }); route.data = out.viewModel; route.start(); </script>