1
0
mirror of synced 2025-02-16 20:53:13 +03:00

Adds support for deterministic ids

This commit is contained in:
Justin Schroeder 2020-05-01 15:58:40 -04:00
parent 35ab510f85
commit aed01eb4ff
6 changed files with 30 additions and 5 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -51,9 +51,11 @@ class Formulate {
uploadJustCompleteDuration: 1000,
errorHandler: (err) => err,
plugins: [ en ],
locales: {}
locales: {},
idPrefix: 'formulate-'
}
this.registry = new Map()
this.idRegistry = {}
}
/**
@ -73,6 +75,21 @@ class Formulate {
}
}
/**
* Produce a deterministically generated id based on the sequence by which it
* was requested. This should be *theoretically* the same SSR as client side.
* However, SSR and deterministic ids can be very challenging, so this
* implementation is open to community review.
*/
nextId (vm) {
const path = vm.$route && vm.$route.path && vm.$route.path || false
const pathPrefix = path ? vm.$route.path.replace(/[\/\\.\s]/g, '-') : 'global';
if (!Object.prototype.hasOwnProperty.call(this.idRegistry, pathPrefix)) {
this.idRegistry[pathPrefix] = 0;
}
return `${this.options.idPrefix}${pathPrefix}-${++this.idRegistry[pathPrefix]}`
}
/**
* Given a set of options, apply them to the pre-existing options.
* @param {Object} extendWith

View File

@ -190,7 +190,7 @@ export default {
},
data () {
return {
defaultId: nanoid(9),
defaultId: this.$formulate.nextId(this),
localAttributes: {},
internalModelProxy: this.getInitialValue(),
behavioralErrorVisibility: (this.errorBehavior === 'live'),

View File

@ -207,4 +207,12 @@ describe('FormulateInputBox', () => {
expect(wrapper.contains(FormulateInputGroup)).toBe(true)
expect(wrapper.find('input[type="checkbox"]').exists()).toBe(false)
})
it('renders multiple labels both with correct id', async () => {
const wrapper = mount(FormulateInput, { propsData: { type: 'checkbox', label: 'VueFormulate FTW!'} })
const id = wrapper.find('input[type="checkbox"]').attributes('id')
const labelIds = wrapper.findAll('label').wrappers.map(label => label.attributes('for'));
expect(labelIds.length).toBe(2);
expect(labelIds.filter(labelId => labelId === id).length).toBe(2);
})
})