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

Merge pull request #77 from wearebraid/feature/deterministic-ids

Feature/deterministic ids
This commit is contained in:
Justin Schroeder 2020-05-04 16:09:10 -04:00 committed by GitHub
commit ff35dc0ea4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 32 additions and 8 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

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{
"name": "@braid/vue-formulate",
"version": "2.2.10",
"version": "2.2.11",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@ -1,6 +1,6 @@
{
"name": "@braid/vue-formulate",
"version": "2.2.10",
"version": "2.2.11",
"description": "The easiest way to build forms in Vue.",
"main": "dist/formulate.umd.js",
"module": "dist/formulate.esm.js",

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 || 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

@ -60,7 +60,6 @@
<script>
import context from './libs/context'
import { shallowEqualObjects, parseRules, snakeToCamel } from './libs/utils'
import nanoid from 'nanoid/non-secure'
export default {
name: 'FormulateInput',
@ -190,7 +189,7 @@ export default {
},
data () {
return {
defaultId: nanoid(9),
defaultId: this.$formulate.nextId(this),
localAttributes: {},
internalModelProxy: this.getInitialValue(),
behavioralErrorVisibility: (this.errorBehavior === 'live'),

View File

@ -217,4 +217,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);
})
})