Skip to content

Commit 2235218

Browse files
authored
Merge pull request #51 from 14nrv/dev
2 parents 69b158d + 5932805 commit 2235218

File tree

8 files changed

+341
-132
lines changed

8 files changed

+341
-132
lines changed

README.md

+12-10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
[![NPM Version](https://img.shields.io/npm/v/vue-form-json.svg)](https://www.npmjs.com/package/vue-form-json)
2-
[![Build Status](https://travis-ci.org/14nrv/vue-form-json.svg?branch=dev)](https://travis-ci.org/14nrv/vue-form-json)
2+
[![Build Status](https://travis-ci.com/14nrv/vue-form-json.svg?branch=dev)](https://travis-ci.com/14nrv/vue-form-json)
33
[![Test Coverage](https://api.codeclimate.com/v1/badges/af5a15db118dac6343ab/test_coverage)](https://codeclimate.com/github/14nrv/vue-form-json/test_coverage)
44
[![Maintainability](https://api.codeclimate.com/v1/badges/af5a15db118dac6343ab/maintainability)](https://codeclimate.com/github/14nrv/vue-form-json/maintainability)
55
[![semantic-release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg)](https://github.com/semantic-release/semantic-release)
@@ -38,11 +38,15 @@ Once submitted, an event 'formSubmitted' is emitted on $root with the formName a
3838
label: 'the label'
3939
}]
4040
```
41-
- [x] Scoped slot everywhere inside form
41+
- [x] Scoped slot everywhere inside the form
4242
```js
4343
const formFields = [{ slot: 'nameOfTheSlot', props: { foo: 'bar' } }]
4444
```
45-
- [x] Html directly inside json (formFields props)
45+
- [x] Custom fields support inside scoped slot
46+
```html
47+
<template #nameOfTheSlot="{ foo, updateFormValues, isFormReseted }">
48+
```
49+
- [x] Html support
4650
```js
4751
const formFields = [{ html: '<p>Your html content</p>' }]
4852
```
@@ -83,6 +87,10 @@ Object.keys(rules).forEach(rule => {
8387
</template>
8488

8589
<script>
90+
// import 'bulma/css/bulma.min.css'
91+
// import '@fortawesome/fontawesome-free/css/all.min.css'
92+
// import 'vue-form-json/dist/vue-form-json.css'
93+
8694
import formJson from 'vue-form-json'
8795
import jsonFields from './../assets/fields'
8896
@@ -92,19 +100,13 @@ Object.keys(rules).forEach(rule => {
92100
formJson
93101
},
94102
mounted () {
95-
this.$root.$on('formSubmitted', values => alert(JSON.stringify(values)))
103+
this.$root.$on('formSubmitted', values => console.log(values))
96104
},
97105
computed: {
98106
jsonFields: () => jsonFields
99107
}
100108
}
101109
</script>
102-
103-
<style lang="stylus">
104-
@require '../node_modules/bulma/css/bulma.min.css'
105-
@require '../node_modules/@fortawesome/fontawesome-free/css/all.min.css'
106-
@require '../node_modules/vue-form-json/dist/vue-form-json.css'
107-
</style>
108110
```
109111

110112
## Props available on formJson component

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
"humps": "^2.0.1",
6666
"ramda": "^0.27.0",
6767
"slugify": "^1.4.4",
68-
"vee-validate": "^3.4.2",
68+
"vee-validate": "^3.4.5",
6969
"vue": "^2.6.12"
7070
},
7171
"devDependencies": {

src/components/Fields/Control.vue

+11-6
Original file line numberDiff line numberDiff line change
@@ -23,25 +23,30 @@
2323

2424
<script>
2525
import { slug } from '@/helpers'
26+
import Checkbox from '@/components/Fields/Checkbox'
2627
import Input from '@/components/Fields/Input'
28+
import Radio from '@/components/Fields/Radio'
2729
import Select from '@/components/Fields/Select'
2830
import Textarea from '@/components/Fields/Textarea'
29-
import Checkbox from '@/components/Fields/Checkbox'
30-
import Radio from '@/components/Fields/Radio'
3131
32-
const NOT_NORMAL_INPUT = ['textarea', 'select', 'checkbox', 'radio']
32+
const NOT_NORMAL_INPUT = [
33+
'checkbox',
34+
'radio',
35+
'select',
36+
'textarea'
37+
]
3338
3439
export default {
3540
name: 'Control',
3641
filters: {
3742
slugify: value => slug(value)
3843
},
3944
components: {
45+
appCheckbox: Checkbox,
4046
appInput: Input,
47+
appRadio: Radio,
4148
appSelect: Select,
42-
appTextarea: Textarea,
43-
appCheckbox: Checkbox,
44-
appRadio: Radio
49+
appTextarea: Textarea
4550
},
4651
data: () => ({
4752
value: undefined

src/components/Fields/Select.spec.js

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import matchers from 'jest-vue-matcher'
2+
import { mount, createLocalVue } from '@vue/test-utils'
3+
import { ValidationProvider, ValidationObserver } from 'vee-validate'
4+
import { extendRules, slug } from '@/helpers'
5+
import Form from '@/components/Form'
6+
7+
extendRules()
8+
9+
const localVue = createLocalVue()
10+
localVue.component('ValidationProvider', ValidationProvider)
11+
localVue.component('ValidationObserver', ValidationObserver)
12+
localVue.filter('slugify', str => slug(str))
13+
14+
let wrapper
15+
16+
const selectFormField = [{
17+
label: 'Country',
18+
type: 'select',
19+
iconLeft: 'globe-americas',
20+
placeholder: 'Select your option',
21+
options: [
22+
'Afghanistan',
23+
'Åland Islands'
24+
]
25+
}]
26+
27+
const setup = ({
28+
formFields = selectFormField
29+
} = {}) => {
30+
wrapper = mount(Form, {
31+
localVue,
32+
propsData: {
33+
formName: 'testSelect',
34+
formFields
35+
}
36+
})
37+
expect.extend(matchers(wrapper))
38+
return {
39+
wrapper,
40+
getAllOptions: () => wrapper.find('select').findAll('option')
41+
}
42+
}
43+
44+
describe('Select', () => {
45+
it('has multiple options', () => {
46+
const { wrapper } = setup()
47+
const options = wrapper.findAll('select > option')
48+
expect(options).toHaveLength(3)
49+
})
50+
51+
it('has a first option disabled & selected as placeholder', () => {
52+
const { wrapper } = setup()
53+
54+
const firstOption = wrapper.findAll('select > option').at(0)
55+
const { disabled, text } = firstOption.element
56+
57+
expect(firstOption.attributes('selected')).toBe('selected')
58+
expect(disabled).toBe(true)
59+
expect(text).toBe(selectFormField[0].placeholder)
60+
})
61+
62+
it('has no value by default', () => {
63+
setup()
64+
expect('select').toHaveValue('')
65+
})
66+
67+
it('changes value', async () => {
68+
const { getAllOptions, wrapper } = setup()
69+
await getAllOptions().at(1).setSelected()
70+
71+
const expectedValue = selectFormField[0].options[0]
72+
const expectedFormValues = { [selectFormField[0].label]: expectedValue }
73+
expect('select').toHaveValue(expectedValue)
74+
expect(wrapper.vm.formValues).toStrictEqual(expectedFormValues)
75+
})
76+
77+
it('changes the selected options to the placeholder on reset', async () => {
78+
const { getAllOptions, wrapper } = setup()
79+
await getAllOptions().at(1).setSelected()
80+
81+
wrapper.find('input[type=reset]').trigger('reset')
82+
83+
expect('select').toHaveValue('')
84+
expect(wrapper.vm.$el.querySelector('select').selectedIndex).toBe(0)
85+
})
86+
87+
it('removes selected options on reset if no placeholder', async () => {
88+
const [{ placeholder, ...rest }] = selectFormField
89+
const { getAllOptions, wrapper } = setup({ formFields: [rest] })
90+
await getAllOptions().at(1).setSelected()
91+
92+
wrapper.find('input[type=reset]').trigger('reset')
93+
94+
expect(wrapper.vm.$el.querySelector('select').selectedIndex).toBe(0)
95+
})
96+
})

0 commit comments

Comments
 (0)