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>
<b-input-group>
<b-input
<b-input-group v-bind="$attrs">
<input-item
:id="id" :placeholder="placeholder"
:state="state" :aria-describedby="feedbackId"
v-model="value[0]" @update="$emit('input', value)"
:state="state" :aria-describedby="id + 'local-part-desc'"
v-model="value.localPart"
v-on="listeners"
/>
<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-select
v-model="value[1]" :options="options" @change="$emit('input', value)"
<select-item
v-model="value.domain"
:choices="choices"
:aria-describedby="id + 'domain-desc'"
/>
</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>
</template>
<script>
export default {
name: 'AdressInputSelect',
inheritAttrs: false,
props: {
// `value` is actually passed thru the `v-model` directive
value: { type: Array, required: true },
options: { type: Array, required: true },
separator: { type: String, default: '@' },
value: { type: Object, required: true },
choices: { type: Array, required: true },
placeholder: { type: String, default: null },
id: { type: String, 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>
<style lang="scss" scoped>
.input-group-append ~ .input-group-append {
min-width: 40%;
flex-basis: 40%;
}
select {
border-top-left-radius: 0;

View file

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

View file

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

View file

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