demos/forms/extended-make-model-year.html
<my-mmy></my-mmy>
<script src="../../node_modules/steal/steal.js" dev-bundle main="@empty" id="demo-source">
import { ajax, fixture, QueryLogic, StacheElement, type } from "can";
fixture.delay = 1200;
fixture("/makes", fixture.store([
{ id: "1", name: "Ford" },
{ id: "2", name: "Nissan" }
],
{ identity: ["id"] }
));
fixture("/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 ] },
],
{ identity: ["id"] }
));
fixture("/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"},
],
{ identity: ["id"] }
));
class MyMmy extends StacheElement {
static view = `
<select value:bind="this.makeId"
{{# if(this.makes.isPending) }}disabled{{/ if }}>
{{# if(this.makes.isPending) }}
<option value=''>Loading...</option>
{{ else }}
{{^ this.makeId }}
<option value=''>Select a Make</option>
{{/ this.makeId }}
{{# for( make of this.makes.value) }}
<option value:from="make.id">{{ make.name }}</option>
{{/ for }}
{{/ if }}
</select>
{{# if(this.modelsPromise) }}
{{# if(this.models) }}
<select value:bind="this.modelId">
{{^ this.modelId }}
<option value=''>Select a Model</option>
{{/ this.modelId }}
{{# for(model of this.models) }}
<option value:from="model.id">{{ model.name }}</option>
{{/ for }}
</select>
{{ else }}
<select disabled><option>Loading Models</option></select>
{{/ if }}
{{ else }}
<select disabled><option>Models</option></select>
{{/ if }}
{{# if(this.years) }}
<select value:bind="this.year">
{{^ this.year }}
<option value=''>Select a Year</option>
{{/ this.year }}
{{# for(year of this.years ) }}
<option value:from="year">{{ year }}</option>
{{/ for }}
</select>
{{ else }}
<select disabled><option>Years</option></select>
{{/ if }}
<div>
{{# for(vehicle of this.vehicles) }}
<h2>{{ vehicle.name }}</h2>
<img src:from="vehicle.thumb" width="200px"/>
{{/ for }}
</div>
`;
static props = {
makeId: type.maybeConvert(String),
makes: {
get() {
return ajax({
type: "GET",
url: "/makes"
}).then(resp => resp.data);
}
},
modelId: {
type: String,
value({ lastSet, listenTo, resolve }) {
listenTo(lastSet, resolve);
listenTo("makeId", () => resolve(""));
}
},
get modelsPromise() {
let makeId = this.makeId;
if( makeId ) {
return ajax({
type: "GET",
url: "/models",
data: { filter: { makeId } }
}).then(resp => {
return resp.data;
});
}
},
models: {
async(resolve) {
let promise = this.modelsPromise;
if(promise) {
promise.then(resolve);
}
}
},
get model() {
let models = this.models,
modelId = this.modelId;
if(models && models.length && modelId) {
let matched = models.filter(model => {
return modelId == model.id;
});
return matched[0];
}
},
get years() {
let model = this.model;
return model && model.years;
},
year: {
type: String,
value({ lastSet, listenTo, resolve }) {
listenTo(lastSet, resolve);
listenTo("modelId", () => resolve(""));
}
},
vehicles: {
async(resolve) {
let year = this.year,
modelId = this.modelId;
if(modelId && year) {
ajax({
type: "GET",
url: "/vehicles",
data: { filter: { modelId, year } }
}).then(resp => {
resolve(resp.data);
});
} else {
resolve([]);
}
}
}
};
};
customElements.define("my-mmy", MyMmy);
</script>