Skip to content

Commit e26cb2a

Browse files
committed
docs: Add Vuelidate example
closes: #405
1 parent b4c3870 commit e26cb2a

File tree

1 file changed

+140
-0
lines changed

1 file changed

+140
-0
lines changed

docs/feathers-vuex-forms.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,6 +288,146 @@ export default {
288288
</script>
289289
```
290290
291+
### Vuelidate 2 Example
292+
293+
Here's an example of how you might use the upcoming Vuelidate 2 (which is being rewritten to work with the Vue Composition API) to do form validation. Just to be clear, the validation library you use doesn't change how FeathersVuex will work. Since Vuelidate is likely the most popular validation library, this is an example to get you started. There may be some things to figure out to implement your use case. First, you'll need to install these dependencies:
294+
295+
```json
296+
{
297+
"dependencies": {
298+
"@vuelidate/core": "^2.0.0-alpha.0",
299+
"@vuelidate/validators": "^2.0.0-alpha.0"
300+
}
301+
}
302+
```
303+
304+
Here's the full example, complete with TailwindCSS styles.
305+
306+
```html
307+
<template>
308+
<div class="permission-creator flex flex-row items-end">
309+
<!-- Org Selector -->
310+
<label class="block w-full">
311+
<span class="select-label text-gray-700">Add Organization</span>
312+
<XSelect
313+
v-model="selectedOrg"
314+
:items="filteredOrgs"
315+
:label="makeOrgLabel"
316+
clearable
317+
placeholder="Select an Organization"
318+
class="block"
319+
:input-class="[
320+
'x-select-button px-2 py-2 border rounded bg-white',
321+
$v.org.$dirty && $v.org.$invalid
322+
? 'border-red-400'
323+
: 'border-gray-400'
324+
]"
325+
@click="$v.org.$touch"
326+
/>
327+
</label>
328+
329+
<!-- Permission Selector -->
330+
<label class="block ml-0.5">
331+
<span class="select-label text-gray-700">Permission</span>
332+
<PermissionSelect v-model="selectedAccessType" />
333+
</label>
334+
335+
<button
336+
class="form-button primary ml-0.5"
337+
:disabled="$v.$invalid"
338+
@click="validateAndCreate"
339+
>
340+
Add
341+
</button>
342+
</div>
343+
</template>
344+
345+
<script>
346+
import { XSelect } from '@rovit/x-select'
347+
import PermissionSelect from '../PermissionSelect/PermissionSelect'
348+
import { models, useFind } from 'feathers-vuex'
349+
import { computed, ref } from '@vue/composition-api'
350+
import keyBy from 'lodash/keyBy'
351+
import capitalize from 'voca/capitalize'
352+
import useVuelidate from '@vuelidate/core'
353+
import { required } from '@vuelidate/validators'
354+
355+
export default {
356+
name: 'PermissionCreatorOrg',
357+
components: {
358+
XSelect,
359+
PermissionSelect
360+
},
361+
props: {
362+
excludeIds: {
363+
type: Array,
364+
default: () => []
365+
}
366+
},
367+
setup(props, context) {
368+
const { Org } = models.api
369+
370+
const selectedOrg = ref(null)
371+
const selectedAccessType = ref('view')
372+
373+
// Fetch orgs
374+
const orgsParams = computed(() => {
375+
return { query: {} }
376+
})
377+
const { items: orgs } = useFind({ model: Org, params: orgsParams })
378+
379+
const filteredOrgs = computed(() => {
380+
const excludeIds = keyBy(props.excludeIds)
381+
return orgs.value.filter(org => {
382+
return !excludeIds[org._id]
383+
})
384+
})
385+
386+
const $v = useVuelidate(
387+
{
388+
org: { required, $autoDirty: true },
389+
accessType: { required, $autoDirty: true }
390+
},
391+
{ org: selectedOrg, accessType: selectedAccessType }
392+
)
393+
394+
function validateAndCreate() {
395+
const org = selectedOrg.value
396+
const accessType = selectedAccessType.value
397+
398+
if (!$v.$invalid) context.emit('create', { org, accessType })
399+
400+
selectedOrg.value = null
401+
selectedAccessType.value = 'view'
402+
403+
// Not currently working, so the org select turns red after removal
404+
$v.org.$reset()
405+
}
406+
407+
function makeOrgLabel(org) {
408+
let label = `${org.name}`
409+
if (org.nameOfOwner) {
410+
label += ` (${org.nameOfOwner})`
411+
}
412+
return label
413+
}
414+
415+
return {
416+
selectedOrg,
417+
selectedAccessType,
418+
filteredOrgs,
419+
validateAndCreate,
420+
capitalize,
421+
$v,
422+
makeOrgLabel
423+
}
424+
}
425+
}
426+
</script>
427+
428+
<style lang="postcss"></style>
429+
```
430+
291431
## FeathersVuexInputWrapper
292432
293433
Building on the same ideas as the FeathersVuexFormWrapper, the FeathersVuexInputWrapper reduces boilerplate for working with the clone and commit pattern on a single input. One use case for this component is implementing an "edit-in-place" workflow. The following example shows how to use the FeathersVuexInputWrapper to automatically save a record upon `blur` on a text input:

0 commit comments

Comments
 (0)