mirror of
https://gitee.com/ant-design-vue/ant-design-vue.git
synced 2024-11-30 11:08:00 +08:00
doc: form add demo (#5070)
* doc: add form demo * fix: form dynamic error * doc: add form demo * revert: formitem auto validate #4955 * fix: input not update when set undefined * doc: add form demo * fix: form validate for number tyope, close #5064 * fix: form validateMessages not work * doc: add form demo
This commit is contained in:
parent
1c9cfd19e6
commit
7aae6f675c
@ -93,7 +93,7 @@ export type FormExpose = {
|
||||
resetFields: (name?: NamePath) => void;
|
||||
clearValidate: (name?: NamePath) => void;
|
||||
validateFields: (
|
||||
nameList?: NamePath[],
|
||||
nameList?: NamePath[] | string,
|
||||
options?: ValidateOptions,
|
||||
) => Promise<{
|
||||
[key: string]: any;
|
||||
@ -102,7 +102,7 @@ export type FormExpose = {
|
||||
[key: string]: any;
|
||||
};
|
||||
validate: (
|
||||
nameList?: NamePath[],
|
||||
nameList?: NamePath[] | string,
|
||||
options?: ValidateOptions,
|
||||
) => Promise<{
|
||||
[key: string]: any;
|
||||
@ -145,7 +145,12 @@ const Form = defineComponent({
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
const validateMessages = computed(() => {
|
||||
return {
|
||||
...defaultValidateMessages,
|
||||
...props.validateMessages,
|
||||
};
|
||||
});
|
||||
const formClassName = computed(() =>
|
||||
classNames(prefixCls.value, {
|
||||
[`${prefixCls.value}-${props.layout}`]: true,
|
||||
@ -267,10 +272,7 @@ const Form = defineComponent({
|
||||
// Add field validate rule in to promise list
|
||||
if (!provideNameList || containsNamePath(namePathList, fieldNamePath)) {
|
||||
const promise = field.validateRules({
|
||||
validateMessages: {
|
||||
...defaultValidateMessages,
|
||||
...props.validateMessages,
|
||||
},
|
||||
validateMessages: validateMessages.value,
|
||||
...options,
|
||||
});
|
||||
|
||||
@ -376,6 +378,7 @@ const Form = defineComponent({
|
||||
onValidate: (name, status, errors) => {
|
||||
emit('validate', name, status, errors);
|
||||
},
|
||||
validateMessages,
|
||||
});
|
||||
|
||||
watch(
|
||||
|
@ -1,4 +1,4 @@
|
||||
import type { PropType, ExtractPropTypes, ComputedRef } from 'vue';
|
||||
import type { PropType, ExtractPropTypes, ComputedRef, Ref } from 'vue';
|
||||
import {
|
||||
watch,
|
||||
defineComponent,
|
||||
@ -32,7 +32,7 @@ const ValidateStatuses = tuple('success', 'warning', 'error', 'validating', '');
|
||||
export type ValidateStatus = typeof ValidateStatuses[number];
|
||||
|
||||
export interface FieldExpose {
|
||||
fieldValue: ComputedRef<any>;
|
||||
fieldValue: Ref<any>;
|
||||
fieldId: ComputedRef<any>;
|
||||
fieldName: ComputedRef<any>;
|
||||
resetField: () => void;
|
||||
@ -132,13 +132,15 @@ export default defineComponent({
|
||||
return formName ? `${formName}_${mergedId}` : `${defaultItemNamePrefixCls}_${mergedId}`;
|
||||
}
|
||||
});
|
||||
const fieldValue = computed(() => {
|
||||
const getNewFieldValue = () => {
|
||||
const model = formContext.model.value;
|
||||
if (!model || !fieldName.value) {
|
||||
return;
|
||||
} else {
|
||||
return getPropByPath(model, namePath.value, true).v;
|
||||
}
|
||||
return getPropByPath(model, namePath.value, true).v;
|
||||
});
|
||||
};
|
||||
const fieldValue = computed(() => getNewFieldValue());
|
||||
|
||||
const initialValue = ref(cloneDeep(fieldValue.value));
|
||||
const mergedValidateTrigger = computed(() => {
|
||||
@ -184,9 +186,20 @@ export default defineComponent({
|
||||
watchEffect(() => {
|
||||
validateState.value = props.validateStatus;
|
||||
});
|
||||
|
||||
const messageVariables = computed(() => {
|
||||
let variables: Record<string, string> = {};
|
||||
if (typeof props.label === 'string') {
|
||||
variables.label = props.label;
|
||||
} else if (props.name) {
|
||||
variables.label = String(name);
|
||||
}
|
||||
if (props.messageVariables) {
|
||||
variables = { ...variables, ...props.messageVariables };
|
||||
}
|
||||
return variables;
|
||||
});
|
||||
const validateRules = (options: ValidateOptions) => {
|
||||
const { validateFirst = false, messageVariables } = props;
|
||||
const { validateFirst = false } = props;
|
||||
const { triggerName } = options || {};
|
||||
|
||||
let filteredRules = rulesRef.value;
|
||||
@ -207,9 +220,12 @@ export default defineComponent({
|
||||
namePath.value,
|
||||
fieldValue.value,
|
||||
filteredRules as RuleObject[],
|
||||
options,
|
||||
{
|
||||
validateMessages: formContext.validateMessages.value,
|
||||
...options,
|
||||
},
|
||||
validateFirst,
|
||||
messageVariables,
|
||||
messageVariables.value,
|
||||
);
|
||||
validateState.value = 'validating';
|
||||
errors.value = [];
|
||||
@ -285,12 +301,6 @@ export default defineComponent({
|
||||
resetField,
|
||||
});
|
||||
|
||||
// instead useProvideFormItemContext onFieldChange
|
||||
watch(fieldValue, () => {
|
||||
if (props.autoLink) {
|
||||
onFieldChange();
|
||||
}
|
||||
});
|
||||
useProvideFormItemContext(
|
||||
{
|
||||
id: fieldId,
|
||||
@ -300,9 +310,9 @@ export default defineComponent({
|
||||
}
|
||||
},
|
||||
onFieldChange: () => {
|
||||
// if (props.autoLink) {
|
||||
// onFieldChange();
|
||||
// }
|
||||
if (props.autoLink) {
|
||||
onFieldChange();
|
||||
}
|
||||
},
|
||||
clearValidate,
|
||||
},
|
||||
|
@ -1,101 +1,181 @@
|
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
|
||||
|
||||
exports[`renders ./components/form/demo/basic.vue correctly 1`] = `
|
||||
<form class="ant-form ant-form-horizontal">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-4 ant-form-item-label"><label class="" title="Activity name">Activity name
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-14 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input type="text" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-4 ant-form-item-label"><label class="" title="Activity zone">Activity zone
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-14 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content">
|
||||
<div class="ant-select ant-select-single ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="rc_select_TEST_OR_SSR" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="rc_select_TEST_OR_SSR_list" aria-autocomplete="list" aria-controls="rc_select_TEST_OR_SSR_list" aria-activedescendant="rc_select_TEST_OR_SSR_list_0" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder">please select your zone</span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-4 ant-form-item-label"><label class="" title="Activity time">Activity time
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-14 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content">
|
||||
<!---->
|
||||
<div class="ant-picker" style="width: 100%;">
|
||||
<div class="ant-picker-input"><input readonly="" placeholder="Pick a date" title="" size="21" autocomplete="off"><span class="ant-picker-suffix"><span role="img" aria-label="calendar" class="anticon anticon-calendar"><svg focusable="false" class="" data-icon="calendar" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M880 184H712v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H384v-64c0-4.4-3.6-8-8-8h-56c-4.4 0-8 3.6-8 8v64H144c-17.7 0-32 14.3-32 32v664c0 17.7 14.3 32 32 32h736c17.7 0 32-14.3 32-32V216c0-17.7-14.3-32-32-32zm-40 656H184V460h656v380zM184 392V256h128v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h256v48c0 4.4 3.6 8 8 8h56c4.4 0 8-3.6 8-8v-48h128v136H184z"></path></svg></span></span>
|
||||
exports[`renders ./components/form/demo/advanced-search.vue correctly 1`] = `
|
||||
<div>
|
||||
<form class="ant-form ant-form-horizontal ant-advanced-search-form">
|
||||
<div class="ant-row" style="margin-left: -12px; margin-right: -12px;">
|
||||
<div class="ant-col ant-col-8" style="padding-left: 12px; padding-right: 12px;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="advanced_search_field-1" class="ant-form-item-required" title="field-1">field-1
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-1" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-4 ant-form-item-label"><label class="" title="Instant delivery">Instant delivery
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-14 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button type="button" role="switch" aria-checked="false" class="ant-switch">
|
||||
<!----><span class="ant-switch-inner"><!----></span>
|
||||
</button></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-4 ant-form-item-label"><label class="" title="Activity type">Activity type
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-14 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content">
|
||||
<div class="ant-checkbox-group"><label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="1"><span class="ant-checkbox-inner"></span></span><span>Online</span></label><label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="2"><span class="ant-checkbox-inner"></span></span><span>Promotion</span></label><label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input type="checkbox" class="ant-checkbox-input" value="3"><span class="ant-checkbox-inner"></span></span><span>Offline</span></label></div>
|
||||
<div class="ant-col ant-col-8" style="padding-left: 12px; padding-right: 12px;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="advanced_search_field-2" class="ant-form-item-required" title="field-2">field-2
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-2" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-4 ant-form-item-label"><label class="" title="Resources">Resources
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-14 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content">
|
||||
<div class="ant-radio-group ant-radio-group-outline ant-radio-group-default"><label class="ant-radio-wrapper"><span class="ant-radio"><input type="radio" class="ant-radio-input" value="1"><span class="ant-radio-inner"></span></span><span>Sponsor</span></label><label class="ant-radio-wrapper"><span class="ant-radio"><input type="radio" class="ant-radio-input" value="2"><span class="ant-radio-inner"></span></span><span>Venue</span></label></div>
|
||||
<div class="ant-col ant-col-8" style="padding-left: 12px; padding-right: 12px;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="advanced_search_field-3" class="ant-form-item-required" title="field-3">field-3
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-3" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-col ant-col-8" style="padding-left: 12px; padding-right: 12px;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="advanced_search_field-4" class="ant-form-item-required" title="field-4">field-4
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-4" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-col ant-col-8" style="padding-left: 12px; padding-right: 12px;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="advanced_search_field-5" class="ant-form-item-required" title="field-5">field-5
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-5" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-col ant-col-8" style="padding-left: 12px; padding-right: 12px;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="advanced_search_field-6" class="ant-form-item-required" title="field-6">field-6
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-6" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-col ant-col-8" style="padding-left: 12px; padding-right: 12px; display: none;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="advanced_search_field-7" class="ant-form-item-required" title="field-7">field-7
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-7" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-col ant-col-8" style="padding-left: 12px; padding-right: 12px; display: none;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="advanced_search_field-8" class="ant-form-item-required" title="field-8">field-8
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-8" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-col ant-col-8" style="padding-left: 12px; padding-right: 12px; display: none;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="advanced_search_field-9" class="ant-form-item-required" title="field-9">field-9
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-9" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-col ant-col-8" style="padding-left: 12px; padding-right: 12px; display: none;">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="advanced_search_field-10" class="ant-form-item-required" title="field-10">field-10
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input placeholder="placeholder" type="text" id="advanced_search_field-10" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row">
|
||||
<div class="ant-col ant-col-24" style="text-align: right;"><button class="ant-btn ant-btn-primary" type="submit">
|
||||
<!----><span>Search</span>
|
||||
</button><button style="margin: 0px 8px;" class="ant-btn" type="button">
|
||||
<!----><span>Clear</span>
|
||||
</button><a style="font-size: 12px;"><span role="img" aria-label="down" class="anticon anticon-down"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span> Collapse </a></div>
|
||||
</div>
|
||||
</form>
|
||||
<div class="search-result-list">Search Result List</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/basic.vue correctly 1`] = `
|
||||
<form autocomplete="off" class="ant-form ant-form-horizontal">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-8 ant-form-item-label"><label html-for="basic_username" class="ant-form-item-required" title="Username">Username
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-16 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input type="text" id="basic_username" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
@ -103,12 +183,12 @@ exports[`renders ./components/form/demo/basic.vue correctly 1`] = `
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-4 ant-form-item-label"><label class="" title="Activity form">Activity form
|
||||
<div class="ant-col ant-col-8 ant-form-item-label"><label html-for="basic_password" class="ant-form-item-required" title="Password">Password
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-14 ant-form-item-control">
|
||||
<div class="ant-col ant-col-16 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input type="textarea" class="ant-input"></div>
|
||||
<div class="ant-form-item-control-input-content"><span class="ant-input-affix-wrapper ant-input-password"><!----><input id="basic_password" type="password" class="ant-input"><span class="ant-input-suffix"><!----><span tabindex="-1" role="img" aria-label="eye-invisible" class="anticon anticon-eye-invisible ant-input-password-icon"><svg focusable="false" class="" data-icon="eye-invisible" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 000-51.5zm-63.57-320.64L836 122.88a8 8 0 00-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 000 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 000 11.31L155.17 889a8 8 0 0011.31 0l712.15-712.12a8 8 0 000-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 00-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 01146.2-106.69L401.31 546.2A112 112 0 01396 512z"></path><path d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 00227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 01-112 112z"></path></svg></span></span></span></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
@ -117,12 +197,21 @@ exports[`renders ./components/form/demo/basic.vue correctly 1`] = `
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-col-14 ant-col-offset-4 ant-form-item-control">
|
||||
<div class="ant-col ant-col-16 ant-col-offset-8 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button class="ant-btn ant-btn-primary" type="button">
|
||||
<!----><span>Create</span>
|
||||
</button><button style="margin-left: 10px;" class="ant-btn" type="button">
|
||||
<!----><span>Cancel</span>
|
||||
<div class="ant-form-item-control-input-content"><label class="ant-checkbox-wrapper ant-checkbox-wrapper-checked"><span class="ant-checkbox ant-checkbox-checked"><input id="basic_remember" type="checkbox" class="ant-checkbox-input"><span class="ant-checkbox-inner"></span></span><span>Remember me</span></label></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-col-16 ant-col-offset-8 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button class="ant-btn ant-btn-primary" type="submit">
|
||||
<!----><span>Submit</span>
|
||||
</button></div>
|
||||
<!---->
|
||||
</div>
|
||||
@ -266,6 +355,202 @@ exports[`renders ./components/form/demo/dynamic-form-item.vue correctly 1`] = `
|
||||
</form>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/dynamic-form-items.vue correctly 1`] = `
|
||||
<form class="ant-form ant-form-horizontal">
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button class="ant-btn ant-btn-dashed ant-btn-block" type="button">
|
||||
<!----><span role="img" aria-label="plus" class="anticon anticon-plus"><svg focusable="false" class="" data-icon="plus" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><defs><style></style></defs><path d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"></path><path d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"></path></svg></span><span>Add user</span>
|
||||
</button></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button class="ant-btn ant-btn-primary" type="submit">
|
||||
<!----><span>Submit</span>
|
||||
</button></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/dynamic-form-items-complex.vue correctly 1`] = `
|
||||
<form class="ant-form ant-form-horizontal">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="dynamic_form_nest_item_area" class="ant-form-item-required" title="Area">Area
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content">
|
||||
<div class="ant-select ant-select-single ant-select-show-arrow">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="ant-select-selector"><span class="ant-select-selection-search"><input id="dynamic_form_nest_item_area" autocomplete="off" class="ant-select-selection-search-input" style="opacity: 0;" role="combobox" aria-haspopup="listbox" aria-owns="dynamic_form_nest_item_area_list" aria-autocomplete="list" aria-controls="dynamic_form_nest_item_area_list" aria-activedescendant="dynamic_form_nest_item_area_list_0" readonly="" unselectable="on" type="search"></span>
|
||||
<!----><span class="ant-select-selection-placeholder"><!----></span>
|
||||
</div><span class="ant-select-arrow" style="user-select: none;" unselectable="on" aria-hidden="true"><span role="img" aria-label="down" class="anticon anticon-down ant-select-suffix"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button class="ant-btn ant-btn-dashed ant-btn-block" type="button">
|
||||
<!----><span role="img" aria-label="plus" class="anticon anticon-plus"><svg focusable="false" class="" data-icon="plus" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><defs><style></style></defs><path d="M482 152h60q8 0 8 8v704q0 8-8 8h-60q-8 0-8-8V160q0-8 8-8z"></path><path d="M176 474h672q8 0 8 8v60q0 8-8 8H176q-8 0-8-8v-60q0-8 8-8z"></path></svg></span><span>Add sights</span>
|
||||
</button></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button class="ant-btn ant-btn-primary" type="submit">
|
||||
<!----><span>Submit</span>
|
||||
</button></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/dynamic-rule.vue correctly 1`] = `
|
||||
<form class="ant-form ant-form-horizontal">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-4 ant-form-item-label"><label html-for="dynamic_rule_username" class="ant-form-item-required" title="Username">Username
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-8 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input type="text" id="dynamic_rule_username" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-4 ant-form-item-label"><label html-for="dynamic_rule_nickname" class="" title="Nickname">Nickname
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-8 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input type="text" id="dynamic_rule_nickname" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-col-8 ant-col-offset-4 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><label class="ant-checkbox-wrapper"><span class="ant-checkbox"><input id="dynamic_rule_checkNick" type="checkbox" class="ant-checkbox-input"><span class="ant-checkbox-inner"></span></span><span>Nickname is required</span></label></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-col-8 ant-col-offset-4 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button class="ant-btn ant-btn-primary" type="button">
|
||||
<!----><span>Check</span>
|
||||
</button></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/form-context.vue correctly 1`] = `
|
||||
<form class="ant-form ant-form-horizontal">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-8 ant-form-item-label"><label html-for="form_context_group" class="ant-form-item-required" title="Group Name">Group Name
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-16 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input type="text" id="form_context_group" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-8 ant-form-item-label"><label class="" title="User List">User List
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-16 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><span class="ant-typography ant-typography-secondary ant-form-text"> ( <span role="img" aria-label="smile" class="anticon anticon-smile"><svg focusable="false" class="" data-icon="smile" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M288 421a48 48 0 1096 0 48 48 0 10-96 0zm352 0a48 48 0 1096 0 48 48 0 10-96 0zM512 64C264.6 64 64 264.6 64 512s200.6 448 448 448 448-200.6 448-448S759.4 64 512 64zm263 711c-34.2 34.2-74 61-118.3 79.8C611 874.2 562.3 884 512 884c-50.3 0-99-9.8-144.8-29.2A370.4 370.4 0 01248.9 775c-34.2-34.2-61-74-79.8-118.3C149.8 611 140 562.3 140 512s9.8-99 29.2-144.8A370.4 370.4 0 01249 248.9c34.2-34.2 74-61 118.3-79.8C413 149.8 461.7 140 512 140c50.3 0 99 9.8 144.8 29.2A370.4 370.4 0 01775.1 249c34.2 34.2 61 74 79.8 118.3C874.2 413 884 461.7 884 512s-9.8 99-29.2 144.8A368.89 368.89 0 01775 775zM664 533h-48.1c-4.2 0-7.8 3.2-8.1 7.4C604 589.9 562.5 629 512 629s-92.1-39.1-95.8-88.6c-.3-4.2-3.9-7.4-8.1-7.4H360a8 8 0 00-8 8.4c4.4 84.3 74.5 151.6 160 151.6s155.6-67.3 160-151.6a8 8 0 00-8-8.4z"></path></svg></span> No user yet. )
|
||||
<!----></span>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-col-16 ant-col-offset-8 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button class="ant-btn ant-btn-primary" type="submit">
|
||||
<!----><span>Submit</span>
|
||||
</button><button style="margin: 0px 8px;" class="ant-btn" type="button">
|
||||
<!----><span>Add User</span>
|
||||
</button></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
<!---->
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/form-in-modal.vue correctly 1`] = `
|
||||
<div><button class="ant-btn ant-btn-primary" type="button">
|
||||
<!----><span>New Collection</span>
|
||||
</button>
|
||||
<!---->
|
||||
</div>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/horizontal-login.vue correctly 1`] = `
|
||||
<form class="ant-form ant-form-inline">
|
||||
<div class="ant-row ant-form-item">
|
||||
@ -310,6 +595,52 @@ exports[`renders ./components/form/demo/horizontal-login.vue correctly 1`] = `
|
||||
</form>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/inline-login.vue correctly 1`] = `
|
||||
<form autocomplete="off" class="ant-form ant-form-inline">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="horizontal_login_username" class="ant-form-item-required" title="Username">Username
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><span class="ant-input-affix-wrapper"><span class="ant-input-prefix"><span role="img" aria-label="user" class="anticon anticon-user site-form-item-icon"><svg focusable="false" class="" data-icon="user" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"></path></svg></span></span><input type="text" id="horizontal_login_username" class="ant-input">
|
||||
<!----></span>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="horizontal_login_password" class="ant-form-item-required" title="Password">Password
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><span class="ant-input-affix-wrapper ant-input-password"><span class="ant-input-prefix"><span role="img" aria-label="lock" class="anticon anticon-lock site-form-item-icon"><svg focusable="false" class="" data-icon="lock" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 10-56 0z"></path></svg></span></span><input id="horizontal_login_password" type="password" class="ant-input"><span class="ant-input-suffix"><!----><span tabindex="-1" role="img" aria-label="eye-invisible" class="anticon anticon-eye-invisible ant-input-password-icon"><svg focusable="false" class="" data-icon="eye-invisible" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 000-51.5zm-63.57-320.64L836 122.88a8 8 0 00-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 000 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 000 11.31L155.17 889a8 8 0 0011.31 0l712.15-712.12a8 8 0 000-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 00-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 01146.2-106.69L401.31 546.2A112 112 0 01396 512z"></path><path d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 00227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 01-112 112z"></path></svg></span></span></span></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button disabled="" class="ant-btn ant-btn-primary" type="submit">
|
||||
<!----><span>Log in</span>
|
||||
</button></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/lable-width.vue correctly 1`] = `
|
||||
<form class="ant-form ant-form-horizontal">
|
||||
<div class="ant-row ant-form-item">
|
||||
@ -460,52 +791,151 @@ exports[`renders ./components/form/demo/layout.vue correctly 1`] = `
|
||||
</form>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/nested-form.vue correctly 1`] = `
|
||||
<div>
|
||||
<form class="ant-form ant-form-horizontal">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-4 ant-form-item-label"><label html-for="form_item_name" class="ant-form-item-required" title="Activity name">Activity name
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-14 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input type="text" id="form_item_name" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
exports[`renders ./components/form/demo/nest-messages.vue correctly 1`] = `
|
||||
<form class="ant-form ant-form-horizontal">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-8 ant-form-item-label"><label html-for="nest-messages_user_name" class="ant-form-item-required" title="Name">Name
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-16 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input type="text" id="nest-messages_user_name" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-4 ant-form-item-label"><label html-for="form_item_sub_name" class="ant-form-item-required" title="Sub name">Sub name
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-14 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input type="text" id="form_item_sub_name" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-col-14 ant-col-offset-4 ant-form-item-control">
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-8 ant-form-item-label"><label html-for="nest-messages_user_email" class="" title="Email">Email
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-16 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input type="text" id="nest-messages_user_email" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-8 ant-form-item-label"><label html-for="nest-messages_user_age" class="" title="Age">Age
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-16 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content">
|
||||
<div class="ant-input-number">
|
||||
<div class="ant-input-number-handler-wrap"><span unselectable="on" role="button" aria-label="Increase Value" aria-disabled="false" class="ant-input-number-handler ant-input-number-handler-up"><span role="img" aria-label="up" class="anticon anticon-up ant-input-number-handler-up-inner"><svg focusable="false" class="" data-icon="up" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M890.5 755.3L537.9 269.2c-12.8-17.6-39-17.6-51.7 0L133.5 755.3A8 8 0 00140 768h75c5.1 0 9.9-2.5 12.9-6.6L512 369.8l284.1 391.6c3 4.1 7.8 6.6 12.9 6.6h75c6.5 0 10.3-7.4 6.5-12.7z"></path></svg></span></span><span unselectable="on" role="button" aria-label="Decrease Value" aria-disabled="false" class="ant-input-number-handler ant-input-number-handler-down"><span role="img" aria-label="down" class="anticon anticon-down ant-input-number-handler-down-inner"><svg focusable="false" class="" data-icon="down" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M884 256h-75c-5.1 0-9.9 2.5-12.9 6.6L512 654.2 227.9 262.6c-3-4.1-7.8-6.6-12.9-6.6h-75c-6.5 0-10.3 7.4-6.5 12.7l352.6 486.1c12.8 17.6 39 17.6 51.7 0l352.6-486.1c3.9-5.3.1-12.7-6.4-12.7z"></path></svg></span></span></div>
|
||||
<div class="ant-input-number-input-wrap"><input autocomplete="off" role="spinbutton" step="1" class="ant-input-number-input"></div>
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-8 ant-form-item-label"><label html-for="nest-messages_user_website" class="" title="Website">Website
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-16 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><input type="text" id="nest-messages_user_website" class="ant-input"></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-col-8 ant-form-item-label"><label html-for="nest-messages_user_introduction" class="" title="Introduction">Introduction
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-col-16 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><textarea id="nest-messages_user_introduction" class="ant-input"></textarea></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-col-16 ant-col-offset-8 ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button class="ant-btn ant-btn-primary" type="submit">
|
||||
<!----><span>Submit</span>
|
||||
</button></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/normal-login.vue correctly 1`] = `
|
||||
<form class="ant-form ant-form-horizontal login-form">
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="normal_login_username" class="ant-form-item-required" title="Username">Username
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><span class="ant-input-affix-wrapper"><span class="ant-input-prefix"><span role="img" aria-label="user" class="anticon anticon-user site-form-item-icon"><svg focusable="false" class="" data-icon="user" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M858.5 763.6a374 374 0 00-80.6-119.5 375.63 375.63 0 00-119.5-80.6c-.4-.2-.8-.3-1.2-.5C719.5 518 760 444.7 760 362c0-137-111-248-248-248S264 225 264 362c0 82.7 40.5 156 102.8 201.1-.4.2-.8.3-1.2.5-44.8 18.9-85 46-119.5 80.6a375.63 375.63 0 00-80.6 119.5A371.7 371.7 0 00136 901.8a8 8 0 008 8.2h60c4.4 0 7.9-3.5 8-7.8 2-77.2 33-149.5 87.8-204.3 56.7-56.7 132-87.9 212.2-87.9s155.5 31.2 212.2 87.9C779 752.7 810 825 812 902.2c.1 4.4 3.6 7.8 8 7.8h60a8 8 0 008-8.2c-1-47.8-10.9-94.3-29.5-138.2zM512 534c-45.9 0-89.1-17.9-121.6-50.4S340 407.9 340 362c0-45.9 17.9-89.1 50.4-121.6S466.1 190 512 190s89.1 17.9 121.6 50.4S684 316.1 684 362c0 45.9-17.9 89.1-50.4 121.6S557.9 534 512 534z"></path></svg></span></span><input type="text" id="normal_login_username" class="ant-input">
|
||||
<!----></span>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<div class="ant-col ant-form-item-label"><label html-for="normal_login_password" class="ant-form-item-required" title="Password">Password
|
||||
<!---->
|
||||
</label></div>
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><span class="ant-input-affix-wrapper ant-input-password"><span class="ant-input-prefix"><span role="img" aria-label="lock" class="anticon anticon-lock site-form-item-icon"><svg focusable="false" class="" data-icon="lock" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M832 464h-68V240c0-70.7-57.3-128-128-128H388c-70.7 0-128 57.3-128 128v224h-68c-17.7 0-32 14.3-32 32v384c0 17.7 14.3 32 32 32h640c17.7 0 32-14.3 32-32V496c0-17.7-14.3-32-32-32zM332 240c0-30.9 25.1-56 56-56h248c30.9 0 56 25.1 56 56v224H332V240zm460 600H232V536h560v304zM484 701v53c0 4.4 3.6 8 8 8h40c4.4 0 8-3.6 8-8v-53a48.01 48.01 0 10-56 0z"></path></svg></span></span><input id="normal_login_password" type="password" class="ant-input"><span class="ant-input-suffix"><!----><span tabindex="-1" role="img" aria-label="eye-invisible" class="anticon anticon-eye-invisible ant-input-password-icon"><svg focusable="false" class="" data-icon="eye-invisible" width="1em" height="1em" fill="currentColor" aria-hidden="true" viewBox="64 64 896 896"><path d="M942.2 486.2Q889.47 375.11 816.7 305l-50.88 50.88C807.31 395.53 843.45 447.4 874.7 512 791.5 684.2 673.4 766 512 766q-72.67 0-133.87-22.38L323 798.75Q408 838 512 838q288.3 0 430.2-300.3a60.29 60.29 0 000-51.5zm-63.57-320.64L836 122.88a8 8 0 00-11.32 0L715.31 232.2Q624.86 186 512 186q-288.3 0-430.2 300.3a60.3 60.3 0 000 51.5q56.69 119.4 136.5 191.41L112.48 835a8 8 0 000 11.31L155.17 889a8 8 0 0011.31 0l712.15-712.12a8 8 0 000-11.32zM149.3 512C232.6 339.8 350.7 258 512 258c54.54 0 104.13 9.36 149.12 28.39l-70.3 70.3a176 176 0 00-238.13 238.13l-83.42 83.42C223.1 637.49 183.3 582.28 149.3 512zm246.7 0a112.11 112.11 0 01146.2-106.69L401.31 546.2A112 112 0 01396 512z"></path><path d="M508 624c-3.46 0-6.87-.16-10.25-.47l-52.82 52.82a176.09 176.09 0 00227.42-227.42l-52.82 52.82c.31 3.38.47 6.79.47 10.25a111.94 111.94 0 01-112 112z"></path></svg></span></span></span></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<div class="login-form-wrap">
|
||||
<div class="ant-row ant-form-item" no-style="">
|
||||
<!---->
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button class="ant-btn ant-btn-primary" type="button">
|
||||
<!----><span>Create</span>
|
||||
</button><button style="margin-left: 10px;" class="ant-btn" type="button">
|
||||
<!----><span>Reset</span>
|
||||
</button></div>
|
||||
<div class="ant-form-item-control-input-content"><label class="ant-checkbox-wrapper ant-checkbox-wrapper-checked"><span class="ant-checkbox ant-checkbox-checked"><input id="normal_login_remember" type="checkbox" class="ant-checkbox-input"><span class="ant-checkbox-inner"></span></span><span>Remember me</span></label></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</div><a class="login-form-forgot" href="">Forgot password</a>
|
||||
</div>
|
||||
<div class="ant-row ant-form-item">
|
||||
<!---->
|
||||
<div class="ant-col ant-form-item-control">
|
||||
<div class="ant-form-item-control-input">
|
||||
<div class="ant-form-item-control-input-content"><button class="ant-btn ant-btn-primary login-form-button" disabled="" type="submit">
|
||||
<!----><span>Log in</span>
|
||||
</button> Or <a href="">register now!</a></div>
|
||||
<!---->
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/form/demo/useForm-basic.vue correctly 1`] = `
|
||||
|
@ -3,7 +3,8 @@ import { inject, provide, computed } from 'vue';
|
||||
import type { ColProps } from '../grid';
|
||||
import type { RequiredMark, ValidationRule } from './Form';
|
||||
import type { ValidateStatus, FieldExpose } from './FormItem';
|
||||
import type { FormLabelAlign } from './interface';
|
||||
import type { FormLabelAlign, ValidateMessages } from './interface';
|
||||
import { defaultValidateMessages } from './utils/messages';
|
||||
|
||||
export interface FormContextProps {
|
||||
model?: ComputedRef<any>;
|
||||
@ -24,6 +25,7 @@ export interface FormContextProps {
|
||||
status: boolean,
|
||||
errors: string[] | null,
|
||||
) => void;
|
||||
validateMessages: ComputedRef<ValidateMessages>;
|
||||
}
|
||||
|
||||
export const FormContextKey: InjectionKey<FormContextProps> = Symbol('formContextKey');
|
||||
@ -44,6 +46,7 @@ export const useInjectForm = () => {
|
||||
rules: computed(() => undefined),
|
||||
requiredMark: computed(() => false),
|
||||
onValidate: () => {},
|
||||
validateMessages: computed(() => defaultValidateMessages),
|
||||
});
|
||||
};
|
||||
|
||||
|
113
components/form/demo/advanced-search.vue
Normal file
113
components/form/demo/advanced-search.vue
Normal file
@ -0,0 +1,113 @@
|
||||
<docs>
|
||||
---
|
||||
order: 13
|
||||
title:
|
||||
zh-CN: 高级搜索
|
||||
en-US: Advanced search
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
三列栅格式的表单排列方式,常用于数据表格的高级搜索。
|
||||
|
||||
有部分定制的样式代码,由于输入标签长度不确定,需要根据具体情况自行调整。
|
||||
|
||||
## en-US
|
||||
|
||||
Three columns layout is often used for advanced searching of data table.
|
||||
|
||||
Because the width of label is not fixed, you may need to adjust it by customizing its style.
|
||||
|
||||
</docs>
|
||||
<template>
|
||||
<div>
|
||||
<a-form
|
||||
ref="formRef"
|
||||
name="advanced_search"
|
||||
class="ant-advanced-search-form"
|
||||
:model="formState"
|
||||
@finish="onFinish"
|
||||
>
|
||||
<a-row :gutter="24">
|
||||
<template v-for="i in 10" :key="i">
|
||||
<a-col v-show="expand || i <= 6" :span="8">
|
||||
<a-form-item
|
||||
:name="`field-${i}`"
|
||||
:label="`field-${i}`"
|
||||
:rules="[{ required: true, message: 'input something' }]"
|
||||
>
|
||||
<a-input v-model:value="formState[`field-${i}`]" placeholder="placeholder"></a-input>
|
||||
</a-form-item>
|
||||
</a-col>
|
||||
</template>
|
||||
</a-row>
|
||||
<a-row>
|
||||
<a-col :span="24" style="text-align: right">
|
||||
<a-button type="primary" html-type="submit">Search</a-button>
|
||||
<a-button style="margin: 0 8px" @click="() => formRef.resetFields()">Clear</a-button>
|
||||
<a style="font-size: 12px" @click="expand = !expand">
|
||||
<template v-if="expand">
|
||||
<UpOutlined />
|
||||
</template>
|
||||
<template v-else>
|
||||
<DownOutlined />
|
||||
</template>
|
||||
Collapse
|
||||
</a>
|
||||
</a-col>
|
||||
</a-row>
|
||||
</a-form>
|
||||
<div class="search-result-list">Search Result List</div>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, ref } from 'vue';
|
||||
import { DownOutlined, UpOutlined } from '@ant-design/icons-vue';
|
||||
import type { FormInstance } from 'ant-design-vue';
|
||||
export default defineComponent({
|
||||
components: {
|
||||
DownOutlined,
|
||||
UpOutlined,
|
||||
},
|
||||
setup() {
|
||||
const expand = ref(false);
|
||||
const formRef = ref<FormInstance>();
|
||||
const formState = reactive({});
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Received values of form: ', values);
|
||||
console.log('formState: ', formState);
|
||||
};
|
||||
return {
|
||||
formRef,
|
||||
formState,
|
||||
expand,
|
||||
onFinish,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style>
|
||||
#components-form-demo-advanced-search .ant-form {
|
||||
max-width: none;
|
||||
}
|
||||
#components-form-demo-advanced-search .search-result-list {
|
||||
margin-top: 16px;
|
||||
border: 1px dashed #e9e9e9;
|
||||
border-radius: 2px;
|
||||
background-color: #fafafa;
|
||||
min-height: 200px;
|
||||
text-align: center;
|
||||
padding-top: 80px;
|
||||
}
|
||||
[data-theme='dark'] .ant-advanced-search-form {
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
border: 1px solid #434343;
|
||||
padding: 24px;
|
||||
border-radius: 2px;
|
||||
}
|
||||
[data-theme='dark'] #components-form-demo-advanced-search .search-result-list {
|
||||
border: 1px dashed #434343;
|
||||
background: rgba(255, 255, 255, 0.04);
|
||||
}
|
||||
</style>
|
@ -15,83 +15,66 @@ title:
|
||||
Basic Form data control. Includes layout, initial values, validation and submit.
|
||||
</docs>
|
||||
<template>
|
||||
<a-form :model="formState" :label-col="labelCol" :wrapper-col="wrapperCol">
|
||||
<a-form-item label="Activity name">
|
||||
<a-input v-model:value="formState.name" />
|
||||
<a-form
|
||||
:model="formState"
|
||||
name="basic"
|
||||
:label-col="{ span: 8 }"
|
||||
:wrapper-col="{ span: 16 }"
|
||||
autocomplete="off"
|
||||
@finish="onFinish"
|
||||
@finishFailed="onFinishFailed"
|
||||
>
|
||||
<a-form-item
|
||||
label="Username"
|
||||
name="username"
|
||||
:rules="[{ required: true, message: 'Please input your username!' }]"
|
||||
>
|
||||
<a-input v-model:value="formState.username" />
|
||||
</a-form-item>
|
||||
<a-form-item label="Activity zone">
|
||||
<a-select v-model:value="formState.region" placeholder="please select your zone">
|
||||
<a-select-option value="shanghai">Zone one</a-select-option>
|
||||
<a-select-option value="beijing">Zone two</a-select-option>
|
||||
</a-select>
|
||||
|
||||
<a-form-item
|
||||
label="Password"
|
||||
name="password"
|
||||
:rules="[{ required: true, message: 'Please input your password!' }]"
|
||||
>
|
||||
<a-input-password v-model:value="formState.password" />
|
||||
</a-form-item>
|
||||
<a-form-item label="Activity time">
|
||||
<a-date-picker
|
||||
v-model:value="formState.date1"
|
||||
show-time
|
||||
type="date"
|
||||
placeholder="Pick a date"
|
||||
style="width: 100%"
|
||||
/>
|
||||
|
||||
<a-form-item name="remember" :wrapper-col="{ offset: 8, span: 16 }">
|
||||
<a-checkbox v-model:checked="formState.remember">Remember me</a-checkbox>
|
||||
</a-form-item>
|
||||
<a-form-item label="Instant delivery">
|
||||
<a-switch v-model:checked="formState.delivery" />
|
||||
</a-form-item>
|
||||
<a-form-item label="Activity type">
|
||||
<a-checkbox-group v-model:value="formState.type">
|
||||
<a-checkbox value="1" name="type">Online</a-checkbox>
|
||||
<a-checkbox value="2" name="type">Promotion</a-checkbox>
|
||||
<a-checkbox value="3" name="type">Offline</a-checkbox>
|
||||
</a-checkbox-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="Resources">
|
||||
<a-radio-group v-model:value="formState.resource">
|
||||
<a-radio value="1">Sponsor</a-radio>
|
||||
<a-radio value="2">Venue</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
<a-form-item label="Activity form">
|
||||
<a-input v-model:value="formState.desc" type="textarea" />
|
||||
</a-form-item>
|
||||
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
|
||||
<a-button type="primary" @click="onSubmit">Create</a-button>
|
||||
<a-button style="margin-left: 10px">Cancel</a-button>
|
||||
|
||||
<a-form-item :wrapper-col="{ offset: 8, span: 16 }">
|
||||
<a-button type="primary" html-type="submit">Submit</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { Dayjs } from 'dayjs';
|
||||
import { defineComponent, reactive, toRaw } from 'vue';
|
||||
import type { UnwrapRef } from 'vue';
|
||||
import { defineComponent, reactive } from 'vue';
|
||||
|
||||
interface FormState {
|
||||
name: string;
|
||||
region: string | undefined;
|
||||
date1: Dayjs | undefined;
|
||||
delivery: boolean;
|
||||
type: string[];
|
||||
resource: string;
|
||||
desc: string;
|
||||
username: string;
|
||||
password: string;
|
||||
remember: boolean;
|
||||
}
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const formState: UnwrapRef<FormState> = reactive({
|
||||
name: '',
|
||||
region: undefined,
|
||||
date1: undefined,
|
||||
delivery: false,
|
||||
type: [],
|
||||
resource: '',
|
||||
desc: '',
|
||||
const formState = reactive<FormState>({
|
||||
username: '',
|
||||
password: '',
|
||||
remember: true,
|
||||
});
|
||||
const onSubmit = () => {
|
||||
console.log('submit!', toRaw(formState));
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Success:', values);
|
||||
};
|
||||
|
||||
const onFinishFailed = (errorInfo: any) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
};
|
||||
return {
|
||||
labelCol: { span: 4 },
|
||||
wrapperCol: { span: 14 },
|
||||
formState,
|
||||
onSubmit,
|
||||
onFinish,
|
||||
onFinishFailed,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -47,7 +47,7 @@ See more advanced usage at [async-validator](https://github.com/yiminghe/async-v
|
||||
<script lang="ts">
|
||||
import type { RuleObject } from 'ant-design-vue/es/form';
|
||||
import { defineComponent, reactive, ref } from 'vue';
|
||||
import type { UnwrapRef } from 'vue';
|
||||
import type { FormInstance } from 'ant-design-vue';
|
||||
interface FormState {
|
||||
pass: string;
|
||||
checkPass: string;
|
||||
@ -55,8 +55,8 @@ interface FormState {
|
||||
}
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const formRef = ref();
|
||||
const formState: UnwrapRef<FormState> = reactive({
|
||||
const formRef = ref<FormInstance>();
|
||||
const formState = reactive<FormState>({
|
||||
pass: '',
|
||||
checkPass: '',
|
||||
age: undefined,
|
||||
|
@ -15,7 +15,12 @@ title:
|
||||
Add or remove form items dynamically.
|
||||
</docs>
|
||||
<template>
|
||||
<a-form ref="formRef" :model="dynamicValidateForm" v-bind="formItemLayoutWithOutLabel">
|
||||
<a-form
|
||||
ref="formRef"
|
||||
name="dynamic_form_item"
|
||||
:model="dynamicValidateForm"
|
||||
v-bind="formItemLayoutWithOutLabel"
|
||||
>
|
||||
<a-form-item
|
||||
v-for="(domain, index) in dynamicValidateForm.domains"
|
||||
:key="domain.key"
|
||||
@ -56,7 +61,7 @@ Add or remove form items dynamically.
|
||||
<script lang="ts">
|
||||
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons-vue';
|
||||
import { defineComponent, reactive, ref } from 'vue';
|
||||
import type { UnwrapRef } from 'vue';
|
||||
import type { FormInstance } from 'ant-design-vue';
|
||||
|
||||
interface Domain {
|
||||
value: string;
|
||||
@ -68,7 +73,7 @@ export default defineComponent({
|
||||
PlusOutlined,
|
||||
},
|
||||
setup() {
|
||||
const formRef = ref();
|
||||
const formRef = ref<FormInstance>();
|
||||
const formItemLayout = {
|
||||
labelCol: {
|
||||
xs: { span: 24 },
|
||||
@ -85,7 +90,7 @@ export default defineComponent({
|
||||
sm: { span: 20, offset: 4 },
|
||||
},
|
||||
};
|
||||
const dynamicValidateForm: UnwrapRef<{ domains: Domain[] }> = reactive({
|
||||
const dynamicValidateForm = reactive<{ domains: Domain[] }>({
|
||||
domains: [],
|
||||
});
|
||||
const submitForm = () => {
|
||||
|
138
components/form/demo/dynamic-form-items-complex.vue
Normal file
138
components/form/demo/dynamic-form-items-complex.vue
Normal file
@ -0,0 +1,138 @@
|
||||
<docs>
|
||||
---
|
||||
order: 4.2
|
||||
title:
|
||||
zh-CN: 复杂的动态增减表单项
|
||||
en-US: Complex Dynamic Form Item
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
这个例子演示了一个表单中包含多个表单控件的情况。
|
||||
|
||||
## en-US
|
||||
|
||||
This example demonstrates the case that a form contains multiple form controls.
|
||||
|
||||
</docs>
|
||||
<template>
|
||||
<a-form
|
||||
ref="formRef"
|
||||
name="dynamic_form_nest_item"
|
||||
:model="dynamicValidateForm"
|
||||
@finish="onFinish"
|
||||
>
|
||||
<a-form-item name="area" label="Area" :rules="[{ required: true, message: 'Missing area' }]">
|
||||
<a-select v-model:value="dynamicValidateForm.area" :options="areas" />
|
||||
</a-form-item>
|
||||
<a-space
|
||||
v-for="(sight, index) in dynamicValidateForm.sights"
|
||||
:key="sight.id"
|
||||
style="display: flex; margin-bottom: 8px"
|
||||
align="baseline"
|
||||
>
|
||||
<a-form-item
|
||||
:name="['sights', index, 'value']"
|
||||
label="Sight"
|
||||
:rules="{
|
||||
required: true,
|
||||
message: 'Missing sight',
|
||||
}"
|
||||
>
|
||||
<a-select
|
||||
v-model:value="sight.value"
|
||||
:disabled="!dynamicValidateForm.area"
|
||||
:options="(sights[dynamicValidateForm.area] || []).map(a => ({ value: a }))"
|
||||
style="width: 130px"
|
||||
></a-select>
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
label="Price"
|
||||
:name="['sights', index, 'price']"
|
||||
:rules="{
|
||||
required: true,
|
||||
message: 'Missing price',
|
||||
}"
|
||||
>
|
||||
<a-input v-model:value="sight.price" />
|
||||
</a-form-item>
|
||||
<MinusCircleOutlined @click="removeSight(sight)" />
|
||||
</a-space>
|
||||
<a-form-item>
|
||||
<a-button type="dashed" block @click="addSight">
|
||||
<PlusOutlined />
|
||||
Add sights
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" html-type="submit">Submit</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons-vue';
|
||||
import { defineComponent, reactive, ref, watch } from 'vue';
|
||||
import type { FormInstance } from 'ant-design-vue';
|
||||
|
||||
interface Sights {
|
||||
value: string;
|
||||
price: string;
|
||||
id: number;
|
||||
}
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MinusCircleOutlined,
|
||||
PlusOutlined,
|
||||
},
|
||||
setup() {
|
||||
const areas = [
|
||||
{ label: 'Beijing', value: 'Beijing' },
|
||||
{ label: 'Shanghai', value: 'Shanghai' },
|
||||
];
|
||||
|
||||
const sights = {
|
||||
Beijing: ['Tiananmen', 'Great Wall'],
|
||||
Shanghai: ['Oriental Pearl', 'The Bund'],
|
||||
};
|
||||
|
||||
const formRef = ref<FormInstance>();
|
||||
const dynamicValidateForm = reactive<{ sights: Sights[]; area: string }>({
|
||||
sights: [],
|
||||
area: undefined,
|
||||
});
|
||||
watch(
|
||||
() => dynamicValidateForm.area,
|
||||
() => {
|
||||
dynamicValidateForm.sights = [];
|
||||
},
|
||||
);
|
||||
const removeSight = (item: Sights) => {
|
||||
let index = dynamicValidateForm.sights.indexOf(item);
|
||||
if (index !== -1) {
|
||||
dynamicValidateForm.sights.splice(index, 1);
|
||||
}
|
||||
};
|
||||
const addSight = () => {
|
||||
dynamicValidateForm.sights.push({
|
||||
value: undefined,
|
||||
price: undefined,
|
||||
id: Date.now(),
|
||||
});
|
||||
};
|
||||
const onFinish = values => {
|
||||
console.log('Received values of form:', values);
|
||||
console.log('dynamicValidateForm:', dynamicValidateForm);
|
||||
};
|
||||
return {
|
||||
formRef,
|
||||
dynamicValidateForm,
|
||||
onFinish,
|
||||
removeSight,
|
||||
addSight,
|
||||
areas,
|
||||
sights,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
109
components/form/demo/dynamic-form-items.vue
Normal file
109
components/form/demo/dynamic-form-items.vue
Normal file
@ -0,0 +1,109 @@
|
||||
<docs>
|
||||
---
|
||||
order: 4.1
|
||||
title:
|
||||
zh-CN: 动态增减嵌套字段
|
||||
en-US: Dynamic Form nest Items
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
通过数组 name 绑定嵌套字段
|
||||
|
||||
## en-US
|
||||
|
||||
Bind nested fields by array name.
|
||||
|
||||
</docs>
|
||||
<template>
|
||||
<a-form
|
||||
ref="formRef"
|
||||
name="dynamic_form_nest_item"
|
||||
:model="dynamicValidateForm"
|
||||
@finish="onFinish"
|
||||
>
|
||||
<a-space
|
||||
v-for="(user, index) in dynamicValidateForm.users"
|
||||
:key="user.id"
|
||||
style="display: flex; margin-bottom: 8px"
|
||||
align="baseline"
|
||||
>
|
||||
<a-form-item
|
||||
:name="['users', index, 'first']"
|
||||
:rules="{
|
||||
required: true,
|
||||
message: 'Missing first name',
|
||||
}"
|
||||
>
|
||||
<a-input v-model:value="user.first" placeholder="First Name" />
|
||||
</a-form-item>
|
||||
<a-form-item
|
||||
:name="['users', index, 'last']"
|
||||
:rules="{
|
||||
required: true,
|
||||
message: 'Missing last name',
|
||||
}"
|
||||
>
|
||||
<a-input v-model:value="user.last" placeholder="Last Name" />
|
||||
</a-form-item>
|
||||
<MinusCircleOutlined @click="removeUser(user)" />
|
||||
</a-space>
|
||||
<a-form-item>
|
||||
<a-button type="dashed" block @click="addUser">
|
||||
<PlusOutlined />
|
||||
Add user
|
||||
</a-button>
|
||||
</a-form-item>
|
||||
<a-form-item>
|
||||
<a-button type="primary" html-type="submit">Submit</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons-vue';
|
||||
import { defineComponent, reactive, ref } from 'vue';
|
||||
import type { FormInstance } from 'ant-design-vue';
|
||||
|
||||
interface User {
|
||||
first: string;
|
||||
last: string;
|
||||
id: number;
|
||||
}
|
||||
export default defineComponent({
|
||||
components: {
|
||||
MinusCircleOutlined,
|
||||
PlusOutlined,
|
||||
},
|
||||
setup() {
|
||||
const formRef = ref<FormInstance>();
|
||||
const dynamicValidateForm = reactive<{ users: User[] }>({
|
||||
users: [],
|
||||
});
|
||||
const removeUser = (item: User) => {
|
||||
let index = dynamicValidateForm.users.indexOf(item);
|
||||
if (index !== -1) {
|
||||
dynamicValidateForm.users.splice(index, 1);
|
||||
}
|
||||
};
|
||||
const addUser = () => {
|
||||
dynamicValidateForm.users.push({
|
||||
first: '',
|
||||
last: '',
|
||||
id: Date.now(),
|
||||
});
|
||||
};
|
||||
const onFinish = values => {
|
||||
console.log('Received values of form:', values);
|
||||
console.log('dynamicValidateForm.users:', dynamicValidateForm.users);
|
||||
};
|
||||
return {
|
||||
formRef,
|
||||
dynamicValidateForm,
|
||||
onFinish,
|
||||
removeUser,
|
||||
addUser,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
94
components/form/demo/dynamic-rule.vue
Normal file
94
components/form/demo/dynamic-rule.vue
Normal file
@ -0,0 +1,94 @@
|
||||
<docs>
|
||||
---
|
||||
order: 23
|
||||
title:
|
||||
zh-CN: 动态校验规则
|
||||
en-US: Dynamic Rules
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
根据不同情况执行不同的校验规则。
|
||||
|
||||
## en-US
|
||||
|
||||
Perform different check rules according to different situations.
|
||||
|
||||
</docs>
|
||||
<template>
|
||||
<a-form ref="formRef" :model="formState" name="dynamic_rule" v-bind="formItemLayout">
|
||||
<a-form-item
|
||||
label="Username"
|
||||
name="username"
|
||||
:rules="[{ required: true, message: 'Please input your username!' }]"
|
||||
>
|
||||
<a-input v-model:value="formState.username" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="Nickname"
|
||||
name="nickname"
|
||||
:rules="[{ required: formState.checkNick, message: 'Please input your nickname!' }]"
|
||||
>
|
||||
<a-input v-model:value="formState.nickname" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item name="checkNick" v-bind="formTailLayout">
|
||||
<a-checkbox v-model:checked="formState.checkNick">Nickname is required</a-checkbox>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-bind="formTailLayout">
|
||||
<a-button type="primary" @click="onCheck">Check</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, ref, watch } from 'vue';
|
||||
import type { FormInstance } from 'ant-design-vue';
|
||||
|
||||
interface FormState {
|
||||
username: string;
|
||||
nickname: string;
|
||||
checkNick: boolean;
|
||||
}
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const formRef = ref<FormInstance>();
|
||||
const formState = reactive<FormState>({
|
||||
username: '',
|
||||
nickname: '',
|
||||
checkNick: false,
|
||||
});
|
||||
watch(
|
||||
() => formState.checkNick,
|
||||
() => {
|
||||
formRef.value.validateFields(['nickname']);
|
||||
},
|
||||
{ flush: 'post' },
|
||||
);
|
||||
const onCheck = async () => {
|
||||
try {
|
||||
const values = await formRef.value.validateFields();
|
||||
console.log('Success:', values);
|
||||
} catch (errorInfo) {
|
||||
console.log('Failed:', errorInfo);
|
||||
}
|
||||
};
|
||||
const formItemLayout = {
|
||||
labelCol: { span: 4 },
|
||||
wrapperCol: { span: 8 },
|
||||
};
|
||||
const formTailLayout = {
|
||||
labelCol: { span: 4 },
|
||||
wrapperCol: { span: 8, offset: 4 },
|
||||
};
|
||||
return {
|
||||
formState,
|
||||
formItemLayout,
|
||||
formTailLayout,
|
||||
onCheck,
|
||||
formRef,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
148
components/form/demo/form-context.vue
Normal file
148
components/form/demo/form-context.vue
Normal file
@ -0,0 +1,148 @@
|
||||
<docs>
|
||||
---
|
||||
order: 8
|
||||
title:
|
||||
zh-CN: 多表单联动
|
||||
en-US: Control between forms
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
本例子中,Modal 的确认按钮在 Form 之外,通过 `form.submit` 方法调用表单提交功能。反之,则推荐使用 `<Button htmlType="submit" />` 调用 web 原生提交逻辑。
|
||||
|
||||
## en-US
|
||||
|
||||
In this case, submit button is in the Modal which is out of Form. You can use `form.submit` to submit form. Besides, we recommend native `<Button htmlType="submit" />` to submit a form.
|
||||
|
||||
</docs>
|
||||
<template>
|
||||
<a-form ref="formRef" :model="formState" name="form_context" v-bind="layout" @finish="onFinish">
|
||||
<a-form-item
|
||||
name="group"
|
||||
label="Group Name"
|
||||
:rules="[{ required: true, message: 'Please input group name!' }]"
|
||||
>
|
||||
<a-input v-model:value="formState.group" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item label="User List">
|
||||
<template v-if="formState.users.length">
|
||||
<ul>
|
||||
<template v-for="user in formState.users" :key="user.key">
|
||||
<li class="user">
|
||||
<a-avatar>
|
||||
<template #icon><UserOutlined /></template>
|
||||
</a-avatar>
|
||||
{{ user.name }} - {{ user.age }}
|
||||
</li>
|
||||
</template>
|
||||
</ul>
|
||||
</template>
|
||||
<template v-else>
|
||||
<a-typography-text class="ant-form-text" type="secondary">
|
||||
(
|
||||
<SmileOutlined />
|
||||
No user yet. )
|
||||
</a-typography-text>
|
||||
</template>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item v-bind="tailLayout">
|
||||
<a-button html-type="submit" type="primary">Submit</a-button>
|
||||
<a-button html-type="button" style="margin: 0 8px" @click="visible = true">Add User</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
<a-modal v-model:visible="visible" title="Basic Drawer" @ok="onOk">
|
||||
<a-form ref="modalFormRef" :model="modalFormState" layout="vertical" name="userForm">
|
||||
<a-form-item name="name" label="User Name" :rules="[{ required: true }]">
|
||||
<a-input v-model:value="modalFormState.name" />
|
||||
</a-form-item>
|
||||
<a-form-item name="age" label="User Age" :rules="[{ required: true }]">
|
||||
<a-input-number v-model:value="modalFormState.age" />
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, ref, watch, toRaw } from 'vue';
|
||||
import type { FormInstance } from 'ant-design-vue';
|
||||
import { SmileOutlined, UserOutlined } from '@ant-design/icons-vue';
|
||||
|
||||
interface UserType {
|
||||
name?: string;
|
||||
age?: number;
|
||||
key?: number;
|
||||
}
|
||||
|
||||
interface FormState {
|
||||
group: string;
|
||||
users: UserType[];
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
components: {
|
||||
SmileOutlined,
|
||||
UserOutlined,
|
||||
},
|
||||
setup() {
|
||||
const formRef = ref<FormInstance>();
|
||||
const modalFormRef = ref<FormInstance>();
|
||||
const visible = ref(false);
|
||||
const formState = reactive<FormState>({
|
||||
group: '',
|
||||
users: [],
|
||||
});
|
||||
const modalFormState = ref<UserType>({});
|
||||
|
||||
watch(
|
||||
visible,
|
||||
() => {
|
||||
modalFormState.value = {};
|
||||
},
|
||||
{ flush: 'post' },
|
||||
);
|
||||
|
||||
const onOk = () => {
|
||||
modalFormRef.value.validateFields().then(() => {
|
||||
formState.users.push({ ...modalFormState.value, key: Date.now() });
|
||||
visible.value = false;
|
||||
});
|
||||
};
|
||||
const onFinish = () => {
|
||||
console.log('Finish:', toRaw(formState));
|
||||
};
|
||||
const layout = {
|
||||
labelCol: { span: 8 },
|
||||
wrapperCol: { span: 16 },
|
||||
};
|
||||
const tailLayout = {
|
||||
wrapperCol: { offset: 8, span: 16 },
|
||||
};
|
||||
return {
|
||||
formState,
|
||||
layout,
|
||||
tailLayout,
|
||||
formRef,
|
||||
modalFormRef,
|
||||
visible,
|
||||
modalFormState,
|
||||
onOk,
|
||||
onFinish,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
#components-form-demo-form-context .user {
|
||||
margin-bottom: 8px;
|
||||
}
|
||||
|
||||
#components-form-demo-form-context .user .ant-avatar {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.ant-row-rtl #components-form-demo-form-context .user .ant-avatar {
|
||||
margin-right: 0;
|
||||
margin-left: 8px;
|
||||
}
|
||||
</style>
|
97
components/form/demo/form-in-modal.vue
Normal file
97
components/form/demo/form-in-modal.vue
Normal file
@ -0,0 +1,97 @@
|
||||
<docs>
|
||||
---
|
||||
order: 14
|
||||
title:
|
||||
zh-CN: 弹出层中的新建表单
|
||||
en-US: Form in Modal to Create
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
当用户访问一个展示了某个列表的页面,想新建一项但又不想跳转页面时,可以用 Modal 弹出一个表单,用户填写必要信息后创建新的项。
|
||||
|
||||
## en-US
|
||||
|
||||
When user visit a page with a list of items, and want to create a new item. The page can popup a form in Modal, then let user fill in the form to create an item.
|
||||
|
||||
</docs>
|
||||
<template>
|
||||
<div>
|
||||
<a-button type="primary" @click="visible = true">New Collection</a-button>
|
||||
<a-modal
|
||||
v-model:visible="visible"
|
||||
title="Create a new collection"
|
||||
ok-text="Create"
|
||||
cancel-text="Cancel"
|
||||
@ok="onOk"
|
||||
>
|
||||
<a-form ref="formRef" :model="formState" layout="vertical" name="form_in_modal">
|
||||
<a-form-item
|
||||
name="title"
|
||||
label="Title"
|
||||
:rules="[{ required: true, message: 'Please input the title of collection!' }]"
|
||||
>
|
||||
<a-input v-model:value="formState.title" />
|
||||
</a-form-item>
|
||||
<a-form-item name="description" label="Description">
|
||||
<a-input v-model:value="formState.description" type="textarea" />
|
||||
</a-form-item>
|
||||
<a-form-item name="modifier" class="collection-create-form_last-form-item">
|
||||
<a-radio-group v-model:value="formState.modifier">
|
||||
<a-radio value="public">Public</a-radio>
|
||||
<a-radio value="private">Private</a-radio>
|
||||
</a-radio-group>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</a-modal>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, ref, toRaw } from 'vue';
|
||||
import type { FormInstance } from 'ant-design-vue';
|
||||
|
||||
interface Values {
|
||||
title: string;
|
||||
description: string;
|
||||
modifier: string;
|
||||
}
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const formRef = ref<FormInstance>();
|
||||
const visible = ref(false);
|
||||
const formState = reactive<Values>({
|
||||
title: '',
|
||||
description: '',
|
||||
modifier: 'public',
|
||||
});
|
||||
|
||||
const onOk = () => {
|
||||
formRef.value
|
||||
.validateFields()
|
||||
.then(values => {
|
||||
console.log('Received values of form: ', values);
|
||||
console.log('formState: ', toRaw(formState));
|
||||
visible.value = false;
|
||||
formRef.value.resetFields();
|
||||
console.log('reset formState: ', toRaw(formState));
|
||||
})
|
||||
.catch(info => {
|
||||
console.log('Validate Failed:', info);
|
||||
});
|
||||
};
|
||||
|
||||
return {
|
||||
formState,
|
||||
formRef,
|
||||
visible,
|
||||
onOk,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
.collection-create-form_last-form-item {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
</style>
|
@ -4,11 +4,19 @@
|
||||
<LableWidth />
|
||||
<HorizontalLogin />
|
||||
<Layout />
|
||||
<Validation />
|
||||
<inlineLoginVue />
|
||||
<normalLoginVue />
|
||||
<!-- <Validation /> -->
|
||||
<CustomValidation />
|
||||
<DynamicFormItem />
|
||||
<NestedForm />
|
||||
<CustomizedFormControls />
|
||||
<advancedSearchVue />
|
||||
<dynamicFormItemsComplexVue />
|
||||
<dynamicFormItemsVue />
|
||||
<dynamicRuleVue />
|
||||
<formContextVue />
|
||||
<formInModalVue />
|
||||
<UseFormBasic />
|
||||
<UseFormNested />
|
||||
<UseFormTrigger />
|
||||
@ -17,18 +25,26 @@
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
import advancedSearchVue from './advanced-search.vue';
|
||||
import Basic from './basic.vue';
|
||||
import CustomValidation from './custom-validation.vue';
|
||||
import DynamicFormItem from './dynamic-form-item.vue';
|
||||
import dynamicFormItemsComplexVue from './dynamic-form-items-complex.vue';
|
||||
import dynamicFormItemsVue from './dynamic-form-items.vue';
|
||||
import dynamicRuleVue from './dynamic-rule.vue';
|
||||
import formContextVue from './form-context.vue';
|
||||
import formInModalVue from './form-in-modal.vue';
|
||||
import HorizontalLogin from './horizontal-login.vue';
|
||||
import NestedForm from './nested-form.vue';
|
||||
import inlineLoginVue from './inline-login.vue';
|
||||
import LableWidth from './lable-width.vue';
|
||||
import Layout from './layout.vue';
|
||||
import Validation from './validation.vue';
|
||||
import NestedForm from './nest-messages.vue';
|
||||
import normalLoginVue from './normal-login.vue';
|
||||
// import Validation from './validation.vue';
|
||||
import UseFormBasic from './useForm-basic.vue';
|
||||
import UseFormNested from './useForm-nested.vue';
|
||||
import UseFormTrigger from './useForm-trigger.vue';
|
||||
import UseFormMerge from './useForm-merge.vue';
|
||||
import LableWidth from './lable-width.vue';
|
||||
import CustomizedFormControls from './customized-form-controls.vue';
|
||||
import CN from '../index.zh-CN.md';
|
||||
import US from '../index.en-US.md';
|
||||
@ -43,13 +59,21 @@ export default defineComponent({
|
||||
HorizontalLogin,
|
||||
NestedForm,
|
||||
Layout,
|
||||
Validation,
|
||||
// Validation,
|
||||
UseFormBasic,
|
||||
UseFormNested,
|
||||
UseFormTrigger,
|
||||
UseFormMerge,
|
||||
LableWidth,
|
||||
CustomizedFormControls,
|
||||
advancedSearchVue,
|
||||
dynamicFormItemsComplexVue,
|
||||
dynamicFormItemsVue,
|
||||
dynamicRuleVue,
|
||||
formContextVue,
|
||||
formInModalVue,
|
||||
inlineLoginVue,
|
||||
normalLoginVue,
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
91
components/form/demo/inline-login.vue
Normal file
91
components/form/demo/inline-login.vue
Normal file
@ -0,0 +1,91 @@
|
||||
<docs>
|
||||
---
|
||||
order: 10
|
||||
title:
|
||||
zh-CN: 内联登录栏
|
||||
en-US: Inline Login Form
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
内联登录栏,常用在顶部导航栏中。
|
||||
|
||||
## en-US
|
||||
|
||||
Inline login form is often used in navigation bar.
|
||||
|
||||
</docs>
|
||||
<template>
|
||||
<a-form
|
||||
:model="formState"
|
||||
name="horizontal_login"
|
||||
layout="inline"
|
||||
autocomplete="off"
|
||||
@finish="onFinish"
|
||||
@finishFailed="onFinishFailed"
|
||||
>
|
||||
<a-form-item
|
||||
label="Username"
|
||||
name="username"
|
||||
:rules="[{ required: true, message: 'Please input your username!' }]"
|
||||
>
|
||||
<a-input v-model:value="formState.username">
|
||||
<template #prefix>
|
||||
<UserOutlined class="site-form-item-icon" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="Password"
|
||||
name="password"
|
||||
:rules="[{ required: true, message: 'Please input your password!' }]"
|
||||
>
|
||||
<a-input-password v-model:value="formState.password">
|
||||
<template #prefix>
|
||||
<LockOutlined class="site-form-item-icon" />
|
||||
</template>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item>
|
||||
<a-button :disabled="disabled" type="primary" html-type="submit">Log in</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, computed } from 'vue';
|
||||
import { UserOutlined, LockOutlined } from '@ant-design/icons-vue';
|
||||
interface FormState {
|
||||
username: string;
|
||||
password: string;
|
||||
}
|
||||
export default defineComponent({
|
||||
components: {
|
||||
UserOutlined,
|
||||
LockOutlined,
|
||||
},
|
||||
setup() {
|
||||
const formState = reactive<FormState>({
|
||||
username: '',
|
||||
password: '',
|
||||
});
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Success:', values);
|
||||
};
|
||||
|
||||
const onFinishFailed = (errorInfo: any) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
};
|
||||
const disabled = computed(() => {
|
||||
return !(formState.username && formState.password);
|
||||
});
|
||||
return {
|
||||
formState,
|
||||
onFinish,
|
||||
onFinishFailed,
|
||||
disabled,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
86
components/form/demo/nest-messages.vue
Normal file
86
components/form/demo/nest-messages.vue
Normal file
@ -0,0 +1,86 @@
|
||||
<docs>
|
||||
---
|
||||
order: 5
|
||||
title:
|
||||
zh-CN: 嵌套结构与校验信息
|
||||
en-US: Nest
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
`name` 属性支持嵌套数据结构。通过 `validateMessages` 或 `message` 自定义校验信息模板,模板内容可参考[此处](https://github.com/vueComponent/ant-design-vue/blob/next/components/form/utils/messages.ts)。
|
||||
|
||||
## en-US
|
||||
|
||||
`name` prop support nest data structure. Customize validate message template with `validateMessages` or `message`. Ref [here](https://github.com/vueComponent/ant-design-vue/blob/next/components/form/utils/messages.ts) about message template.
|
||||
</docs>
|
||||
<template>
|
||||
<a-form
|
||||
:model="formState"
|
||||
v-bind="layout"
|
||||
name="nest-messages"
|
||||
:validate-messages="validateMessages"
|
||||
@finish="onFinish"
|
||||
>
|
||||
<a-form-item :name="['user', 'name']" label="Name" :rules="[{ required: true }]">
|
||||
<a-input v-model:value="formState.user.name" />
|
||||
</a-form-item>
|
||||
<a-form-item :name="['user', 'email']" label="Email" :rules="[{ type: 'email' }]">
|
||||
<a-input v-model:value="formState.user.email" />
|
||||
</a-form-item>
|
||||
<a-form-item :name="['user', 'age']" label="Age" :rules="[{ type: 'number', min: 0, max: 99 }]">
|
||||
<a-input-number v-model:value="formState.user.age" />
|
||||
</a-form-item>
|
||||
<a-form-item :name="['user', 'website']" label="Website">
|
||||
<a-input v-model:value="formState.user.website" />
|
||||
</a-form-item>
|
||||
<a-form-item :name="['user', 'introduction']" label="Introduction">
|
||||
<a-textarea v-model:value="formState.user.introduction" />
|
||||
</a-form-item>
|
||||
<a-form-item :wrapper-col="{ ...layout.wrapperCol, offset: 8 }">
|
||||
<a-button type="primary" html-type="submit">Submit</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const layout = {
|
||||
labelCol: { span: 8 },
|
||||
wrapperCol: { span: 16 },
|
||||
};
|
||||
|
||||
const validateMessages = {
|
||||
required: '${label} is required!',
|
||||
types: {
|
||||
email: '${label} is not a valid email!',
|
||||
number: '${label} is not a valid number!',
|
||||
},
|
||||
number: {
|
||||
range: '${label} must be between ${min} and ${max}',
|
||||
},
|
||||
};
|
||||
|
||||
const formState = reactive({
|
||||
user: {
|
||||
name: '',
|
||||
age: undefined,
|
||||
email: '',
|
||||
website: '',
|
||||
introduction: '',
|
||||
},
|
||||
});
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Success:', values);
|
||||
};
|
||||
return {
|
||||
formState,
|
||||
onFinish,
|
||||
layout,
|
||||
validateMessages,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
@ -1,89 +0,0 @@
|
||||
<docs>
|
||||
---
|
||||
order: 11
|
||||
title:
|
||||
zh-CN: 嵌套表单
|
||||
en-US: Nested Form
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
嵌套表单
|
||||
|
||||
## en-US
|
||||
|
||||
Nested form.
|
||||
</docs>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<a-form
|
||||
ref="formRef"
|
||||
:model="formState"
|
||||
:rules="rules"
|
||||
:label-col="labelCol"
|
||||
:wrapper-col="wrapperCol"
|
||||
>
|
||||
<a-form-item label="Activity name" name="name">
|
||||
<a-input v-model:value="formState.name" />
|
||||
</a-form-item>
|
||||
<a-form-item label="Sub name" :name="['sub', 'name']">
|
||||
<a-input v-model:value="formState.sub.name" />
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item :wrapper-col="{ span: 14, offset: 4 }">
|
||||
<a-button type="primary" @click="onSubmit">Create</a-button>
|
||||
<a-button style="margin-left: 10px" @click="resetForm">Reset</a-button>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</div>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, ref, toRaw } from 'vue';
|
||||
|
||||
export default defineComponent({
|
||||
setup() {
|
||||
const formRef = ref();
|
||||
const formState = reactive({
|
||||
name: undefined,
|
||||
sub: { name: undefined },
|
||||
});
|
||||
const rules = {
|
||||
name: {
|
||||
required: true,
|
||||
message: 'Please input name',
|
||||
},
|
||||
sub: {
|
||||
name: [
|
||||
{
|
||||
required: true,
|
||||
message: 'Please input name',
|
||||
},
|
||||
],
|
||||
},
|
||||
};
|
||||
const onSubmit = () => {
|
||||
formRef.value
|
||||
.validate()
|
||||
.then(() => {
|
||||
console.log('values', formState, toRaw(formState));
|
||||
})
|
||||
.catch(error => {
|
||||
console.log('error', error);
|
||||
});
|
||||
};
|
||||
const resetForm = () => {
|
||||
formRef.value.resetFields();
|
||||
};
|
||||
return {
|
||||
formRef,
|
||||
labelCol: { span: 4 },
|
||||
wrapperCol: { span: 14 },
|
||||
formState,
|
||||
rules,
|
||||
onSubmit,
|
||||
resetForm,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
119
components/form/demo/normal-login.vue
Normal file
119
components/form/demo/normal-login.vue
Normal file
@ -0,0 +1,119 @@
|
||||
<docs>
|
||||
---
|
||||
order: 11
|
||||
title:
|
||||
zh-CN: 登录框
|
||||
en-US: Login Form
|
||||
---
|
||||
|
||||
## zh-CN
|
||||
|
||||
普通的登录框,可以容纳更多的元素。
|
||||
|
||||
## en-US
|
||||
|
||||
Normal login form which can contain more elements.
|
||||
|
||||
</docs>
|
||||
<template>
|
||||
<a-form
|
||||
:model="formState"
|
||||
name="normal_login"
|
||||
class="login-form"
|
||||
@finish="onFinish"
|
||||
@finishFailed="onFinishFailed"
|
||||
>
|
||||
<a-form-item
|
||||
label="Username"
|
||||
name="username"
|
||||
:rules="[{ required: true, message: 'Please input your username!' }]"
|
||||
>
|
||||
<a-input v-model:value="formState.username">
|
||||
<template #prefix>
|
||||
<UserOutlined class="site-form-item-icon" />
|
||||
</template>
|
||||
</a-input>
|
||||
</a-form-item>
|
||||
|
||||
<a-form-item
|
||||
label="Password"
|
||||
name="password"
|
||||
:rules="[{ required: true, message: 'Please input your password!' }]"
|
||||
>
|
||||
<a-input-password v-model:value="formState.password">
|
||||
<template #prefix>
|
||||
<LockOutlined class="site-form-item-icon" />
|
||||
</template>
|
||||
</a-input-password>
|
||||
</a-form-item>
|
||||
|
||||
<div class="login-form-wrap">
|
||||
<a-form-item name="remember" no-style>
|
||||
<a-checkbox v-model:checked="formState.remember">Remember me</a-checkbox>
|
||||
</a-form-item>
|
||||
<a class="login-form-forgot" href="">Forgot password</a>
|
||||
</div>
|
||||
|
||||
<a-form-item>
|
||||
<a-button :disabled="disabled" type="primary" html-type="submit" class="login-form-button">
|
||||
Log in
|
||||
</a-button>
|
||||
Or
|
||||
<a href="">register now!</a>
|
||||
</a-form-item>
|
||||
</a-form>
|
||||
</template>
|
||||
<script lang="ts">
|
||||
import { defineComponent, reactive, computed } from 'vue';
|
||||
import { UserOutlined, LockOutlined } from '@ant-design/icons-vue';
|
||||
interface FormState {
|
||||
username: string;
|
||||
password: string;
|
||||
remember: boolean;
|
||||
}
|
||||
export default defineComponent({
|
||||
components: {
|
||||
UserOutlined,
|
||||
LockOutlined,
|
||||
},
|
||||
setup() {
|
||||
const formState = reactive<FormState>({
|
||||
username: '',
|
||||
password: '',
|
||||
remember: true,
|
||||
});
|
||||
const onFinish = (values: any) => {
|
||||
console.log('Success:', values);
|
||||
};
|
||||
|
||||
const onFinishFailed = (errorInfo: any) => {
|
||||
console.log('Failed:', errorInfo);
|
||||
};
|
||||
const disabled = computed(() => {
|
||||
return !(formState.username && formState.password);
|
||||
});
|
||||
return {
|
||||
formState,
|
||||
onFinish,
|
||||
onFinishFailed,
|
||||
disabled,
|
||||
};
|
||||
},
|
||||
});
|
||||
</script>
|
||||
<style>
|
||||
#components-form-demo-normal-login .login-form {
|
||||
max-width: 300px;
|
||||
}
|
||||
#components-form-demo-normal-login .login-form-wrap {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
}
|
||||
#components-form-demo-normal-login .login-form-forgot {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
#components-form-demo-normal-login .login-form-button {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
@ -32,6 +32,7 @@ async function validateRule(
|
||||
|
||||
// Bug of `async-validator`
|
||||
delete (cloneRule as any).ruleIndex;
|
||||
delete (cloneRule as any).trigger;
|
||||
|
||||
// We should special handle array validate
|
||||
let subRuleField: RuleObject = null;
|
||||
|
@ -138,9 +138,7 @@ export default defineComponent({
|
||||
watch(
|
||||
() => props.value,
|
||||
() => {
|
||||
if (props.value !== undefined) {
|
||||
stateValue.value = props.value;
|
||||
}
|
||||
stateValue.value = props.value;
|
||||
},
|
||||
);
|
||||
watch(
|
||||
|
@ -1,5 +1,6 @@
|
||||
// debugger tsx
|
||||
import Demo from './demo/demo.vue';
|
||||
import Demo from '../../components/form/demo/normal-login.vue';
|
||||
// import Demo from './demo/demo.vue';
|
||||
|
||||
export default {
|
||||
setup() {},
|
||||
|
Loading…
Reference in New Issue
Block a user