Skip to content

About

Car, motorcycle and truck make and model dropdown for any web page. A dependent make/model picker with live vehicle data: 14,000+ models across 850+ makes from official registers of 14 countries. Zero dependencies, no build step.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Repository files navigation

Car, motorcycle and truck make and model dropdown

The make/model picker you stopped hand-maintaining. make-model-dropdown turns two <select> elements into a dependent make → model dropdown, populated live from the VehiclesDB API: 14,000+ models across 850+ makes, six vehicle kinds — cars, motorcycles (motorbikes), mopeds, vans, trucks and buses — reconciled from official national vehicle registers and refreshed monthly. One kind option turns the same widget into a car picker, a motorcycle picker or a truck picker.

Zero dependencies. No build step. Works with plain HTML forms, React, Vue, Rails, anything that renders a <select>.

Live demo and docs →

Quick start

Get a free publishable API key at vehiclesdb.com (it is safe to ship in page source; lock it to your domain in Settings), then:

<select id="make"></select>
<select id="model"></select>

<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script>
  VehiclesDropdown.attach({
    key: "vdb_pk_your_key",
    make: "#make",
    model: "#model"
  })
</script>

That is the whole integration. The make list loads once (~8 KB gzipped), the model list loads when a make is picked, and both selects submit with your form like any other field.

npm

npm install make-model-dropdown
import VehiclesDropdown from "make-model-dropdown"

VehiclesDropdown.attach({ key: "vdb_pk_your_key", make: "#make", model: "#model" })

Options

VehiclesDropdown.attach({
  key: "vdb_pk_…",        // required — your publishable key
  make: "#make",           // required — <select> element or selector
  model: "#model",         // optional — the dependent model <select>
  year: "#year",           // optional — the model-year <select> (needs `model`)

  kind: "car",             // only one kind: car, motorcycle, moped, van, truck, bus
  country: "de",           // only vehicles evidenced in a register country
  order: "popular",        // models by real-world registrations (default) or "alphabetical"
  topMakes: 40,            // only the N most-registered makes, best first (default: all)
  initialMake: "audi",     // preselect a make on load (slug or name)
  initialModel: "a3",      // preselect a model once its make's models load
  initialYear: 2019,       // preselect a year once its model's years fill
  yearFallback: "range",   // a model with no register span: "range" (default) or "none"
  values: "slug",          // option values: "slug" (default) or "name"
  includeOther: true,      // append "Other / not listed" — pickers should never dead-end
  otherLabel: "Other / not listed", // its text, to translate; the value is always "other"

  search: true,            // searchable combobox instead of a plain select
  logos: true,             // make logos in the list (search mode; free key feature)

  placeholderMake: "Make",
  placeholderModel: "Model",
  placeholderYear: "Year",
  attribution: true,       // the CC-BY credit line (keep it on — see below)

  onChange: ({ make, model, year }) => {}, // `year` only when a year select is attached
  onError: (error) => {}
})

attach returns an instance with .value ({ make, model }, plus year with a year select) and .destroy().

Model year

Booking and quote forms ask for the year, so the widget can fill a third <select>:

VehiclesDropdown.attach({ key: "vdb_pk_your_key", make: "#make", model: "#model", year: "#year" })

Picking a model fills the year select from that model's span, newest first (most bookings are for recent cars); changing the make clears model and year together. onChange then reports { make, model, year }, where year is a number, null when nothing is picked, or "other" for the includeOther escape hatch, exactly like make and model. Without year, nothing changes: the payload stays { make, model }.

The years are register years, not production years: the span runs from the first to the latest year the official registers have the model on record, which can differ from the factory's own dates.

About one model in eight has no span on record (and an "Other / not listed" model never has one). yearFallback decides what those models get:

  • "range" (default): the current year back to 40 years ago. The year field never dead-ends, so a customer whose model the registers cannot date can still book.
  • "none": no years, for forms that would rather not offer years the registers cannot back up. With includeOther the select stays enabled with the placeholder and Other, so that choice can still be made; without it there is nothing to choose, so the select is disabled. The widget only ever undoes its own disabling and never overrides a disabled your page sets.

A year the host supplies (initialYear, or a server-rendered selected option in an edit form) is never dropped: if it falls outside the model's span it is added to the list in its place, selected, and logged once with console.warn.

No extra request is made: the spans come with the model list the widget already loads.

Logos

With logos: true (in search mode) each make renders its badge next to its name in the list, and the selected make's badge sits inside the input, the way a phone input wears its country flag. Coverage is partial by design and any marque can be withdrawn at any time, so the library always falls back to an initial-letter chip — build nothing that assumes a logo exists. Logos are third-party trademarks served for referential display; no license is granted with them.

The combobox input inherits your <select>'s CSS classes, so it dresses like the rest of your form with no extra styling.

Popularity, availability, kinds

The data is the point. Every model carries a global popularity decile from real registration counts (order: "popular" puts the Golf first, not the 412), a per-country availability record (country: "de" drops what Germany has never registered), and a kind: kind: "motorcycle" gives you a motorbike picker with displacement-level names ("CBR600RR", not "CBR"), because that is how riders and registers both speak; kind: "truck" or kind: "van" gives fleet and logistics forms the commercial-vehicle picker they never had; kind: "bus" and kind: "moped" round out the six.

Attribution

The vehicle identity data is CC-BY 4.0 — free for anything, with visible credit. The widget renders the credit line for you; leave attribution: true and you are compliant without reading a license. Paid plans can waive display attribution.

The API underneath

The widget speaks the documented Dropdown Data endpoints: GET /api/v1/makes, GET /api/v1/makes/{slug}/models, and make logos. (GET /api/v1/search is part of the same free surface if you build your own typeahead.) They cost 0 credits and accept publishable keys, so the dropdown never spends your quota. Public keys are deliberately refused everywhere else. Use a private vdb_sk_… key from your backend for the rest of the VehiclesDB API: resolving free-text vehicle strings, full records, imagery, and license-plate validation.

Development

npm ci
npm test

The test suite runs the published UMD artifact in a real DOM implementation and covers dependent loading, the year step and its fallbacks, credential-scoped caches, combobox keyboard/blur behavior, labels, callback isolation, and object-URL cleanup.

License

MIT for this library. Data: identity layer CC-BY 4.0, enrichment proprietary — see vehiclesdb.com/attribution.

Releasing (maintainers)

  1. Bump version in package.json AND the version: string in make-model-dropdown.js, keep them equal.
  2. Re-vendor the dist into the website and verify the two files are byte-for-byte identical. The website's system test drives that copy against the real API, so a broken dist fails its CI.
  3. npm publish (owner ritual, like gem releases).

About

Car, motorcycle and truck make and model dropdown for any web page. A dependent make/model picker with live vehicle data: 14,000+ models across 850+ makes from official registers of 14 countries. Zero dependencies, no build step.

Topics

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages