update form components

This commit is contained in:
Axolotle 2020-10-28 16:49:43 +01:00
parent 8f3180031c
commit 3af30ba5b6
4 changed files with 77 additions and 32 deletions

View file

@ -1,42 +1,76 @@
<template> <template>
<b-input-group> <b-input-group v-bind="$attrs">
<b-input <input-item
:id="id" :placeholder="placeholder" :id="id" :placeholder="placeholder"
:state="state" :aria-describedby="feedbackId" :state="state" :aria-describedby="id + 'local-part-desc'"
v-model="value[0]" @update="$emit('input', value)" v-model="value.localPart"
v-on="listeners"
/> />
<b-input-group-append> <b-input-group-append>
<b-input-group-text>{{ separator }}</b-input-group-text> <b-input-group-text>{{ value.separator }}</b-input-group-text>
</b-input-group-append> </b-input-group-append>
<b-input-group-append> <b-input-group-append>
<b-select <select-item
v-model="value[1]" :options="options" @change="$emit('input', value)" v-model="value.domain"
:choices="choices"
:aria-describedby="id + 'domain-desc'"
/> />
</b-input-group-append> </b-input-group-append>
<span class="sr-only" :id="id + 'local-part-desc'">
{{ localPartDesc || $t('user_mail_local_part_description') }}
</span>
<span class="sr-only" :id="id + 'domain-desc'">
{{ domainDesc || $t('user_mail_domain_description') }}
</span>
</b-input-group> </b-input-group>
</template> </template>
<script> <script>
export default { export default {
name: 'AdressInputSelect', name: 'AdressInputSelect',
inheritAttrs: false,
props: { props: {
// `value` is actually passed thru the `v-model` directive // `value` is actually passed thru the `v-model` directive
value: { type: Array, required: true }, value: { type: Object, required: true },
options: { type: Array, required: true }, choices: { type: Array, required: true },
separator: { type: String, default: '@' },
placeholder: { type: String, default: null }, placeholder: { type: String, default: null },
id: { type: String, default: null }, id: { type: String, default: null },
state: { type: null, default: null }, state: { type: null, default: null },
feedbackId: { type: String, default: null } localPartDesc: { type: String, default: null },
domainDesc: { type: String, default: null }
},
computed: {
listeners: function () {
return Object.assign({},
// Forwards all parent events listeners
this.$listeners,
// Overwrite input behavior so this component can work with v-model
{
input: (event) => {
this.$parent.$emit('touch')
this.$emit('input', this.value)
},
blur: event => {
this.$parent.$emit('touch')
this.$emit('blur', this.value)
}
}
)
}
} }
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.input-group-append ~ .input-group-append { .input-group-append ~ .input-group-append {
min-width: 40%; flex-basis: 40%;
} }
select { select {
border-top-left-radius: 0; border-top-left-radius: 0;

View file

@ -1,5 +1,5 @@
<template> <template>
<b-card class="basic-form"> <b-card class="card-form">
<template v-slot:header> <template v-slot:header>
<h2><icon v-if="icon" :iname="icon" /> {{ title }}</h2> <h2><icon v-if="icon" :iname="icon" /> {{ title }}</h2>
</template> </template>
@ -30,7 +30,7 @@
<script> <script>
export default { export default {
name: 'BasicForm', name: 'CardForm',
props: { props: {
id: { type: String, default: 'ynh-form' }, id: { type: String, default: 'ynh-form' },
@ -62,7 +62,7 @@ export default {
</script> </script>
<style lang="scss"> <style lang="scss">
.basic-form .card-footer { .card-form .card-footer {
display: flex; display: flex;
justify-content: flex-end; justify-content: flex-end;

View file

@ -1,13 +1,11 @@
<template> <template>
<!-- v-bind="$attrs" allow to pass default attrs not specified in this component slots --> <!-- v-bind="$attrs" allow to pass default attrs not specified in this component slots -->
<b-form-group <b-form-group
v-bind="attrs" v-bind="attrs"
:id="id || props.id + '_group'" :id="_id"
:label-for="props.id" :label-for="props.id"
:state="state" :state="state"
:invalid-feedback="errorMessage"
@touch="touch" @touch="touch"
class="mb-4"
> >
<!-- Make field props and state available as scoped slot data --> <!-- Make field props and state available as scoped slot data -->
<slot v-bind="{ self: { ...props, state }, touch }"> <slot v-bind="{ self: { ...props, state }, touch }">
@ -22,9 +20,11 @@
/> />
</slot> </slot>
<!-- {{ validation }} --> <template #invalid-feedback>
<span v-html="errorMessage" />
</template>
<template v-if="description || example || link" v-slot:description> <template v-if="description || example || link" #description>
<div class="d-flex"> <div class="d-flex">
<span v-if="example">{{ $t('form_input_example', { example }) }}</span> <span v-if="example">{{ $t('form_input_example', { example }) }}</span>
@ -50,7 +50,7 @@ export default {
description: { type: String, default: null }, description: { type: String, default: null },
example: { type: String, default: null }, example: { type: String, default: null },
link: { type: Object, default: null }, link: { type: Object, default: null },
// rendered field component props // Rendered field component props
component: { type: String, default: 'InputItem' }, component: { type: String, default: 'InputItem' },
value: { type: null, default: null }, value: { type: null, default: null },
props: { type: Object, default: () => ({}) }, props: { type: Object, default: () => ({}) },
@ -58,18 +58,23 @@ export default {
}, },
computed: { computed: {
_id () {
if (this.id) return this.id
return this.props.id ? this.props.id + '_group' : null
},
attrs () { attrs () {
const attrs = { ...this.$attrs } const attrs = { ...this.$attrs }
const defaultAttrs = { if ('label' in attrs) {
'label-cols-md': 4, const defaultAttrs = {
'label-cols-lg': 2, 'label-cols-md': 4,
'label-class': 'font-weight-bold' 'label-cols-lg': 2,
'label-class': 'font-weight-bold'
}
for (const attr in defaultAttrs) {
if (!(attr in attrs)) attrs[attr] = defaultAttrs[attr]
}
} }
for (const attr in defaultAttrs) {
if (!(attr in attrs)) attrs[attr] = defaultAttrs[attr]
}
return attrs return attrs
}, },
@ -116,3 +121,9 @@ export default {
} }
} }
</script> </script>
<style lang="scss" scoped>
::v-deep .invalid-feedback code {
background-color: $gray-200;
}
</style>

View file

@ -5,7 +5,7 @@
:options="choices" :options="choices"
:required="required" :required="required"
v-on="$listeners" v-on="$listeners"
@blur="$parent.$emit('touch', name)" @blur.native="$emit('blur', value)"
/> />
</template> </template>