Import Mapper
The mapping step of a spreadsheet import: match each column of the file to a field, check the required ones, then preview the rows with their errors.
c2-import-mapper is the step between “choose a file” and “import” in a CSV or spreadsheet import. Each column of the file is a row with its header, its first values and a field picker, already filled by matching the header to the fields’ keys, labels and aliases (“E-mail address” finds Email). A summary lists the required fields and whether a column is mapped to each. A field maps from one column at a time: picking it for a second column takes it from the first, and the change is announced.
Set view="preview" to show the rows as they will be imported: one column per mapped field, each invalid cell tinted with its message under the value (required, type such as email, number or date, options, pattern, and a validate function for your own rules), and a pager. errors-only keeps only the rows to fix.
Give it the file as csv text (it detects the delimiter and reads quoted cells), as columns and rows from a spreadsheet library, or as columns and a dataSource for a file too large to hold in memory. The element never reads the file itself and has no buttons of its own: put Preview, Back and Import in the toolbar or footer slot, switch view, and read mapping, missing, validate() and records().
Import
import '@c2n/components/import-mapper'Usage
- Name, mapped
- Email, mapped
All required fields are mapped 4 of 5 columns mapped
-
Full name Auto-matchedAda LovelaceGrace HopperAlan TuringDon't import
Don't import NameRequiredName EmailRequiredEmail CompanyCompany PhonePhone Customer sinceCustomer since -
E-mail address Auto-matchedada@analytical.iograce(at)navy.milalan@bletchley.orgDon't import
Don't import NameRequiredName EmailRequiredEmail CompanyCompany PhonePhone Customer sinceCustomer since -
Organization Auto-matchedAnalytical EnginesUS NavyBletchley ParkDon't import
Don't import NameRequiredName EmailRequiredEmail CompanyCompany PhonePhone Customer sinceCustomer since -
Signed up Auto-matched2024-03-012024-13-012024-05-17Don't import
Don't import NameRequiredName EmailRequiredEmail CompanyCompany PhonePhone Customer sinceCustomer since -
Notes Not importedVIPCall backDon't import
Don't import NameRequiredName EmailRequiredEmail CompanyCompany PhonePhone Customer sinceCustomer since
3 rows, 1 with errors (2 errors)
| Row | Name | Company | Customer since | |
|---|---|---|---|---|
| 1 | Ada Lovelace | ada@analytical.io | Analytical Engines | 2024-03-01 |
| 2 | Grace Hopper | grace(at)navy.mil Error: Not an email address | US Navy | 2024-13-01 Error: Not a date |
| 3 | Alan Turing | alan@bletchley.org | Bletchley Park | 2024-05-17 |
A typical flow reads the file from c2-upload, maps, previews and imports:
import type { ImportMapper } from '@c2n/components/import-mapper'
const mapper = document.querySelector<ImportMapper>('c2-import-mapper')!
mapper.fields = [
{ key: 'email', label: 'Email', required: true, type: 'email' },
{ key: 'plan', label: 'Plan', options: ['free', 'pro', 'team'] },
{ key: 'seats', label: 'Seats', type: 'integer', validate: (value) => (Number(value) > 500 ? 'At most 500 seats' : null) },
]
upload.addEventListener('files-selected', async ({ detail }) => {
mapper.csv = await detail.files[0].text() // for .xlsx, set `columns` and `rows` from your spreadsheet library
})
mapper.addEventListener('mapping-change', ({ detail }) => {
previewButton.disabled = detail.missing.length > 0
})
previewButton.addEventListener('click', () => (mapper.view = 'preview'))
importButton.addEventListener('click', () => {
const { valid } = mapper.validate()
if (valid) save(mapper.records()) // [{ email: '…', plan: 'pro', seats: '12' }, …]
})