mirror of https://github.com/ElemeFE/element
Form: label-width supports width auto (#14944)
parent
e7fdd3dc50
commit
a408b3dd3f
|
@ -593,7 +593,7 @@ All components in a Form inherit their `size` attribute from that Form. Similarl
|
||||||
| rules | validation rules of form | object | — | — |
|
| rules | validation rules of form | object | — | — |
|
||||||
| inline | whether the form is inline | boolean | — | false |
|
| inline | whether the form is inline | boolean | — | false |
|
||||||
| label-position | position of label. If set to 'left' or 'right', `label-width` prop is also required | string | left / right / top | right |
|
| label-position | position of label. If set to 'left' or 'right', `label-width` prop is also required | string | left / right / top | right |
|
||||||
| label-width | width of label, and all its direct child form items will inherit this value | string | — | — |
|
| label-width | width of label, e.g. '50px'. All its direct child form items will inherit this value. Width `auto` is supported. | string | — | — |
|
||||||
| label-suffix | suffix of the label | string | — | — |
|
| label-suffix | suffix of the label | string | — | — |
|
||||||
| hide-required-asterisk | whether required fields should have a red asterisk (star) beside their labels | boolean | — | false |
|
| hide-required-asterisk | whether required fields should have a red asterisk (star) beside their labels | boolean | — | false |
|
||||||
| show-message | whether to show the error message | boolean | — | true |
|
| show-message | whether to show the error message | boolean | — | true |
|
||||||
|
@ -623,7 +623,7 @@ All components in a Form inherit their `size` attribute from that Form. Similarl
|
||||||
| ---- | ----| ---- | ---- | ---- |
|
| ---- | ----| ---- | ---- | ---- |
|
||||||
| prop | a key of `model`. In the use of validate and resetFields method, the attribute is required | string | keys of model that passed to `form` |
|
| prop | a key of `model`. In the use of validate and resetFields method, the attribute is required | string | keys of model that passed to `form` |
|
||||||
| label | label | string | — | — |
|
| label | label | string | — | — |
|
||||||
| label-width | width of label, e.g. '50px' | string | — | — |
|
| label-width | width of label, e.g. '50px'. Width `auto` is supported. | string | — | — |
|
||||||
| required | whether the field is required or not, will be determined by validation rules if omitted | boolean | — | false |
|
| required | whether the field is required or not, will be determined by validation rules if omitted | boolean | — | false |
|
||||||
| rules | validation rules of form | object | — | — |
|
| rules | validation rules of form | object | — | — |
|
||||||
| error | field error message, set its value and the field will validate error and show this message immediately | string | — | — |
|
| error | field error message, set its value and the field will validate error and show this message immediately | string | — | — |
|
||||||
|
|
|
@ -607,7 +607,7 @@ Todos los componentes de un formulario heredan su atributo `size`. De manera sim
|
||||||
| rules | Reglas de validación | object | — | — |
|
| rules | Reglas de validación | object | — | — |
|
||||||
| inline | Si el form es inline | boolean | — | false |
|
| inline | Si el form es inline | boolean | — | false |
|
||||||
| label-position | Posicion de la etiqueta | string | left / right / top | right |
|
| label-position | Posicion de la etiqueta | string | left / right / top | right |
|
||||||
| label-width | ancho de la etiqueta, y todos los form items directos descendientes heredarán este valor | string | — | — |
|
| label-width | width of label, e.g. '50px'. All its direct child form items will inherit this value. Width `auto` is supported. | string | — | — |
|
||||||
| label-suffix | sufijo de la etiqueta | string | — | — |
|
| label-suffix | sufijo de la etiqueta | string | — | — |
|
||||||
| hide-required-asterisk | si los campos obligatorios deben tener un asterisco rojo (estrella) al lado de sus etiquetas | boolean | — | false |
|
| hide-required-asterisk | si los campos obligatorios deben tener un asterisco rojo (estrella) al lado de sus etiquetas | boolean | — | false |
|
||||||
| show-message | si mostrar o no el mensaje de error | boolean | — | true |
|
| show-message | si mostrar o no el mensaje de error | boolean | — | true |
|
||||||
|
@ -638,7 +638,7 @@ Todos los componentes de un formulario heredan su atributo `size`. De manera sim
|
||||||
| -------------- | ------------------------------------------------------------ | ------- | ------------------------------------------- | ----------- |
|
| -------------- | ------------------------------------------------------------ | ------- | ------------------------------------------- | ----------- |
|
||||||
| prop | un clave del modelo. En el uso del método validate and resetFields, el atributo es obligatorio. | string | Clave del modelo que se ha pasado a `form` | |
|
| prop | un clave del modelo. En el uso del método validate and resetFields, el atributo es obligatorio. | string | Clave del modelo que se ha pasado a `form` | |
|
||||||
| label | etiqueta | string | — | — |
|
| label | etiqueta | string | — | — |
|
||||||
| label-width | ancho de la etiqueta, e.g. '50px' | string | — | — |
|
| label-width | ancho de la etiqueta, e.g. '50px'. Width `auto` is supported | string | — | — |
|
||||||
| required | si el campo es obligatorio o no, estará determinado por las reglas de validación si se omite. | boolean | — | false |
|
| required | si el campo es obligatorio o no, estará determinado por las reglas de validación si se omite. | boolean | — | false |
|
||||||
| rules | reglas de validacion del form | object | — | — |
|
| rules | reglas de validacion del form | object | — | — |
|
||||||
| error | mensaje de error de campo, establezca su valor y el campo validará el error y mostrará este mensaje inmediatamente. | string | — | — |
|
| error | mensaje de error de campo, establezca su valor y el campo validará el error y mostrará este mensaje inmediatamente. | string | — | — |
|
||||||
|
|
|
@ -592,7 +592,7 @@ Tout les composants d'un formulaire héritent leur attribut `size` de ce formula
|
||||||
| rules | Règles de validation du formulaire. | object | — | — |
|
| rules | Règles de validation du formulaire. | object | — | — |
|
||||||
| inline | Si le formulaire est horizontal. | boolean | — | false |
|
| inline | Si le formulaire est horizontal. | boolean | — | false |
|
||||||
| label-position | Position des labels. Si 'left' ou 'right', `label-width` est aussi requis. | string | left / right / top | right |
|
| label-position | Position des labels. Si 'left' ou 'right', `label-width` est aussi requis. | string | left / right / top | right |
|
||||||
| label-width | Largeur des labels, tout les enfants directs hériteront de cette valeur. | string | — | — |
|
| label-width | Largeur des labels, tout les enfants directs hériteront de cette valeur. Width `auto` is supported. | string | — | — |
|
||||||
| label-suffix | Suffixe de labels. | string | — | — |
|
| label-suffix | Suffixe de labels. | string | — | — |
|
||||||
| hide-required-asterisk | Si les champs obligatoires doivent avoir une astérisque rouge (étoile) à coté de leurs labels. | boolean | — | false |
|
| hide-required-asterisk | Si les champs obligatoires doivent avoir une astérisque rouge (étoile) à coté de leurs labels. | boolean | — | false |
|
||||||
| show-message | Si le message d'erreur doit apparaître. | boolean | — | true |
|
| show-message | Si le message d'erreur doit apparaître. | boolean | — | true |
|
||||||
|
@ -623,7 +623,7 @@ Tout les composants d'un formulaire héritent leur attribut `size` de ce formula
|
||||||
| ---- | ----| ---- | ---- | ---- |
|
| ---- | ----| ---- | ---- | ---- |
|
||||||
| prop | Une des clés de `model`. Utilisés par les méthodes validate et resetFields. Requis. | string | Clés du model passé à `form`. |
|
| prop | Une des clés de `model`. Utilisés par les méthodes validate et resetFields. Requis. | string | Clés du model passé à `form`. |
|
||||||
| label | Le label. | string | — | — |
|
| label | Le label. | string | — | — |
|
||||||
| label-width | Largeur du label, e.g. '50px'. | string | — | — |
|
| label-width | Largeur du label, e.g. '50px'. Width `auto` is supported. | string | — | — |
|
||||||
| required | Si le champ est requis ou non. Si omis, sera déterminé par les règles de validation. | boolean | — | false |
|
| required | Si le champ est requis ou non. Si omis, sera déterminé par les règles de validation. | boolean | — | false |
|
||||||
| rules | Règles de validation du formulaire. | object | — | — |
|
| rules | Règles de validation du formulaire. | object | — | — |
|
||||||
| error | Message d'erreur du champ. Si il est modifié, le champ l'affichera immédiatement. | string | — | — |
|
| error | Message d'erreur du champ. Si il est modifié, le champ l'affichera immédiatement. | string | — | — |
|
||||||
|
|
|
@ -588,7 +588,7 @@ W3C 标准中有如下[规定](https://www.w3.org/MarkUp/html-spec/html-spec_8.h
|
||||||
| rules | 表单验证规则 | object | — | — |
|
| rules | 表单验证规则 | object | — | — |
|
||||||
| inline | 行内表单模式 | boolean | — | false |
|
| inline | 行内表单模式 | boolean | — | false |
|
||||||
| label-position | 表单域标签的位置,如果值为 left 或者 right 时,则需要设置 `label-width` | string | right/left/top | right |
|
| label-position | 表单域标签的位置,如果值为 left 或者 right 时,则需要设置 `label-width` | string | right/left/top | right |
|
||||||
| label-width | 表单域标签的宽度,作为 Form 直接子元素的 form-item 会继承该值 | string | — | — |
|
| label-width | 表单域标签的宽度,例如 '50px'。作为 Form 直接子元素的 form-item 会继承该值。支持 `auto`。 | string | — | — |
|
||||||
| label-suffix | 表单域标签的后缀 | string | — | — |
|
| label-suffix | 表单域标签的后缀 | string | — | — |
|
||||||
| hide-required-asterisk | 是否显示必填字段的标签旁边的红色星号 | boolean | — | false |
|
| hide-required-asterisk | 是否显示必填字段的标签旁边的红色星号 | boolean | — | false |
|
||||||
| show-message | 是否显示校验错误信息 | boolean | — | true |
|
| show-message | 是否显示校验错误信息 | boolean | — | true |
|
||||||
|
@ -618,7 +618,7 @@ W3C 标准中有如下[规定](https://www.w3.org/MarkUp/html-spec/html-spec_8.h
|
||||||
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
|---------- |-------------- |---------- |-------------------------------- |-------- |
|
||||||
| prop | 表单域 model 字段,在使用 validate、resetFields 方法的情况下,该属性是必填的 | string | 传入 Form 组件的 `model` 中的字段 | — |
|
| prop | 表单域 model 字段,在使用 validate、resetFields 方法的情况下,该属性是必填的 | string | 传入 Form 组件的 `model` 中的字段 | — |
|
||||||
| label | 标签文本 | string | — | — |
|
| label | 标签文本 | string | — | — |
|
||||||
| label-width | 表单域标签的的宽度,例如 '50px' | string | — | — |
|
| label-width | 表单域标签的的宽度,例如 '50px'。支持 `auto`。 | string | — | — |
|
||||||
| required | 是否必填,如不设置,则会根据校验规则自动生成 | boolean | — | false |
|
| required | 是否必填,如不设置,则会根据校验规则自动生成 | boolean | — | false |
|
||||||
| rules | 表单验证规则 | object | — | — |
|
| rules | 表单验证规则 | object | — | — |
|
||||||
| error | 表单域验证错误信息, 设置该值会使表单验证状态变为`error`,并显示该错误信息 | string | — | — |
|
| error | 表单域验证错误信息, 设置该值会使表单验证状态变为`error`,并显示该错误信息 | string | — | — |
|
||||||
|
|
|
@ -9,9 +9,13 @@
|
||||||
},
|
},
|
||||||
sizeClass ? 'el-form-item--' + sizeClass : ''
|
sizeClass ? 'el-form-item--' + sizeClass : ''
|
||||||
]">
|
]">
|
||||||
<label :for="labelFor" class="el-form-item__label" :style="labelStyle" v-if="label || $slots.label">
|
<label-wrap
|
||||||
<slot name="label">{{label + form.labelSuffix}}</slot>
|
:is-auto-width="labelStyle && labelStyle.width === 'auto'"
|
||||||
</label>
|
:update-all="form.labelWidth === 'auto'">
|
||||||
|
<label :for="labelFor" class="el-form-item__label" :style="labelStyle" v-if="label || $slots.label">
|
||||||
|
<slot name="label">{{label + form.labelSuffix}}</slot>
|
||||||
|
</label>
|
||||||
|
</label-wrap>
|
||||||
<div class="el-form-item__content" :style="contentStyle">
|
<div class="el-form-item__content" :style="contentStyle">
|
||||||
<slot></slot>
|
<slot></slot>
|
||||||
<transition name="el-zoom-in-top">
|
<transition name="el-zoom-in-top">
|
||||||
|
@ -39,7 +43,7 @@
|
||||||
import emitter from 'element-ui/src/mixins/emitter';
|
import emitter from 'element-ui/src/mixins/emitter';
|
||||||
import objectAssign from 'element-ui/src/utils/merge';
|
import objectAssign from 'element-ui/src/utils/merge';
|
||||||
import { noop, getPropByPath } from 'element-ui/src/utils/util';
|
import { noop, getPropByPath } from 'element-ui/src/utils/util';
|
||||||
|
import LabelWrap from './label-wrap';
|
||||||
export default {
|
export default {
|
||||||
name: 'ElFormItem',
|
name: 'ElFormItem',
|
||||||
|
|
||||||
|
@ -77,6 +81,10 @@
|
||||||
},
|
},
|
||||||
size: String
|
size: String
|
||||||
},
|
},
|
||||||
|
components: {
|
||||||
|
// use this component to calculate auto width
|
||||||
|
LabelWrap
|
||||||
|
},
|
||||||
watch: {
|
watch: {
|
||||||
error: {
|
error: {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
|
@ -108,7 +116,13 @@
|
||||||
if (this.form.labelPosition === 'top' || this.form.inline) return ret;
|
if (this.form.labelPosition === 'top' || this.form.inline) return ret;
|
||||||
if (!label && !this.labelWidth && this.isNested) return ret;
|
if (!label && !this.labelWidth && this.isNested) return ret;
|
||||||
const labelWidth = this.labelWidth || this.form.labelWidth;
|
const labelWidth = this.labelWidth || this.form.labelWidth;
|
||||||
if (labelWidth) {
|
if (labelWidth === 'auto') {
|
||||||
|
if (this.labelWidth === 'auto') {
|
||||||
|
ret.marginLeft = this.computedLabelWidth;
|
||||||
|
} else if (this.form.labelWidth === 'auto') {
|
||||||
|
ret.marginLeft = this.elForm.autoLabelWidth;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
ret.marginLeft = labelWidth;
|
ret.marginLeft = labelWidth;
|
||||||
}
|
}
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -167,7 +181,8 @@
|
||||||
validateMessage: '',
|
validateMessage: '',
|
||||||
validateDisabled: false,
|
validateDisabled: false,
|
||||||
validator: {},
|
validator: {},
|
||||||
isNested: false
|
isNested: false,
|
||||||
|
computedLabelWidth: ''
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
|
@ -261,6 +276,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
this.validate('change');
|
this.validate('change');
|
||||||
|
},
|
||||||
|
updateComputedLabelWidth(width) {
|
||||||
|
this.computedLabelWidth = width ? `${width}px` : '';
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
mounted() {
|
mounted() {
|
||||||
|
|
|
@ -54,9 +54,16 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
computed: {
|
||||||
|
autoLabelWidth() {
|
||||||
|
const max = Math.max(...this.potentialLabelWidthArr);
|
||||||
|
return max ? `${max}px` : '';
|
||||||
|
}
|
||||||
|
},
|
||||||
data() {
|
data() {
|
||||||
return {
|
return {
|
||||||
fields: []
|
fields: [],
|
||||||
|
potentialLabelWidthArr: [] // use this array to calculate auto width
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created() {
|
created() {
|
||||||
|
@ -142,6 +149,26 @@
|
||||||
fields.forEach(field => {
|
fields.forEach(field => {
|
||||||
field.validate('', cb);
|
field.validate('', cb);
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
getLabelWidthIndex(width) {
|
||||||
|
const index = this.potentialLabelWidthArr.indexOf(width);
|
||||||
|
// it's impossible
|
||||||
|
if (index === -1) {
|
||||||
|
throw new Error('[ElementForm]unpected width ', width);
|
||||||
|
}
|
||||||
|
return index;
|
||||||
|
},
|
||||||
|
registerLabelWidth(val, oldVal) {
|
||||||
|
if (val && oldVal) {
|
||||||
|
const index = this.getLabelWidthIndex(oldVal);
|
||||||
|
this.potentialLabelWidthArr.splice(index, 1, val);
|
||||||
|
} else if (val) {
|
||||||
|
this.potentialLabelWidthArr.push(val);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
deregisterLabelWidth(val) {
|
||||||
|
const index = this.getLabelWidthIndex(val);
|
||||||
|
this.potentialLabelWidthArr.splice(index, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
<script>
|
||||||
|
|
||||||
|
export default {
|
||||||
|
props: {
|
||||||
|
isAutoWidth: Boolean,
|
||||||
|
updateAll: Boolean
|
||||||
|
},
|
||||||
|
|
||||||
|
inject: ['elForm', 'elFormItem'],
|
||||||
|
|
||||||
|
render() {
|
||||||
|
const slots = this.$slots.default;
|
||||||
|
if (!slots) return null;
|
||||||
|
if (this.isAutoWidth) {
|
||||||
|
return (<div class="el-form-item__label-wrap">
|
||||||
|
{ slots }
|
||||||
|
</div>);
|
||||||
|
} else {
|
||||||
|
return slots[0];
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
getLabelWidth() {
|
||||||
|
if (this.$el && this.$el.firstElementChild) {
|
||||||
|
const computedWidth = window.getComputedStyle(this.$el.firstElementChild).width;
|
||||||
|
return Math.ceil(parseFloat(computedWidth));
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
updateLabelWidth(action = 'update') {
|
||||||
|
if (this.$slots.default && this.isAutoWidth && this.$el.firstElementChild) {
|
||||||
|
if (action === 'update') {
|
||||||
|
this.computedWidth = this.getLabelWidth();
|
||||||
|
} else if (action === 'remove') {
|
||||||
|
this.elForm.deregisterLabelWidth(this.computedWidth);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
watch: {
|
||||||
|
computedWidth(val, oldVal) {
|
||||||
|
if (this.updateAll) {
|
||||||
|
this.elForm.registerLabelWidth(val, oldVal);
|
||||||
|
this.elFormItem.updateComputedLabelWidth(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
computedWidth: 0
|
||||||
|
};
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.updateLabelWidth('update');
|
||||||
|
},
|
||||||
|
|
||||||
|
// Is this necessary?
|
||||||
|
// updated() {
|
||||||
|
// this.updateLabelWidth('update');
|
||||||
|
// },
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
this.updateLabelWidth('remove');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
</script>
|
|
@ -84,6 +84,14 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@include e(label-wrap) {
|
||||||
|
float: left;
|
||||||
|
.el-form-item__label {
|
||||||
|
display: inline-block;
|
||||||
|
float: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@include e(label) {
|
@include e(label) {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { createVue, destroyVM } from '../util';
|
import { createVue, destroyVM, waitImmediate } from '../util';
|
||||||
|
|
||||||
const DELAY = 50;
|
const DELAY = 50;
|
||||||
|
|
||||||
|
@ -43,6 +43,43 @@ describe('Form', () => {
|
||||||
expect(vm.$el.querySelector('.el-form-item__content').style.marginLeft).to.equal('80px');
|
expect(vm.$el.querySelector('.el-form-item__content').style.marginLeft).to.equal('80px');
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
|
it('auto label width', async() => {
|
||||||
|
vm = createVue({
|
||||||
|
template: `
|
||||||
|
<el-form ref="form" :model="form" label-width="auto">
|
||||||
|
<el-form-item label="活动名称">
|
||||||
|
<el-input v-model="form.name"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
<el-form-item label="活动备注信息" v-if="display">
|
||||||
|
<el-input v-model="form.name"></el-input>
|
||||||
|
</el-form-item>
|
||||||
|
</el-form>
|
||||||
|
`,
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
display: true,
|
||||||
|
form: {
|
||||||
|
name: '',
|
||||||
|
intro: ''
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
await waitImmediate();
|
||||||
|
|
||||||
|
const formItems = vm.$el.querySelectorAll('.el-form-item__content');
|
||||||
|
const marginLeft = parseInt(formItems[0].style.marginLeft, 10);
|
||||||
|
const marginLeft1 = parseInt(formItems[1].style.marginLeft, 10);
|
||||||
|
expect(marginLeft === marginLeft1).to.be.true;
|
||||||
|
|
||||||
|
vm.display = false;
|
||||||
|
await waitImmediate();
|
||||||
|
|
||||||
|
const formItem = vm.$el.querySelector('.el-form-item__content');
|
||||||
|
const newMarginLeft = parseInt(formItem.style.marginLeft, 10);
|
||||||
|
expect(newMarginLeft < marginLeft).to.be.true;
|
||||||
|
});
|
||||||
it('inline form', done => {
|
it('inline form', done => {
|
||||||
vm = createVue({
|
vm = createVue({
|
||||||
template: `
|
template: `
|
||||||
|
|
Loading…
Reference in New Issue