mirror of
https://github.com/vale981/Vulcan
synced 2025-03-06 01:51:40 -05:00
Add formComponents
prop to forms to enable customizing a specific form's components
This commit is contained in:
parent
bfd336871e
commit
07427a2c96
8 changed files with 61 additions and 33 deletions
|
@ -230,6 +230,15 @@ class SmartForm extends Component {
|
|||
|
||||
return data;
|
||||
};
|
||||
|
||||
/*
|
||||
|
||||
Get form components, in case any has been overwritten for this specific form
|
||||
|
||||
*/
|
||||
getFormComponents = () => {
|
||||
return { ...Components, ...this.props.formComponents }
|
||||
}
|
||||
// --------------------------------------------------------------------- //
|
||||
// -------------------------------- Fields ----------------------------- //
|
||||
// --------------------------------------------------------------------- //
|
||||
|
@ -859,14 +868,15 @@ class SmartForm extends Component {
|
|||
render() {
|
||||
const fieldGroups = this.getFieldGroups();
|
||||
const collectionName = this.getCollection()._name;
|
||||
const FormComponents = this.getFormComponents();
|
||||
|
||||
return (
|
||||
<div className={'document-' + this.getFormType()}>
|
||||
<Formsy.Form onSubmit={this.submitForm} onKeyDown={this.formKeyDown} ref={e => { this.form = e; }}>
|
||||
<Components.FormErrors errors={this.state.errors} />
|
||||
<FormComponents.FormErrors errors={this.state.errors} />
|
||||
|
||||
{fieldGroups.map(group => (
|
||||
<Components.FormGroup
|
||||
<FormComponents.FormGroup
|
||||
key={group.name}
|
||||
{...group}
|
||||
errors={this.state.errors}
|
||||
|
@ -879,12 +889,13 @@ class SmartForm extends Component {
|
|||
formType={this.getFormType()}
|
||||
currentUser={this.props.currentUser}
|
||||
disabled={this.state.disabled}
|
||||
formComponents={FormComponents}
|
||||
/>
|
||||
))}
|
||||
|
||||
{this.props.repeatErrors && this.renderErrors()}
|
||||
|
||||
<Components.FormSubmit
|
||||
<FormComponents.FormSubmit
|
||||
submitLabel={this.props.submitLabel}
|
||||
cancelLabel={this.props.cancelLabel}
|
||||
revertLabel={this.props.revertLabel}
|
||||
|
@ -935,6 +946,7 @@ SmartForm.propTypes = {
|
|||
revertLabel: PropTypes.string,
|
||||
repeatErrors: PropTypes.bool,
|
||||
warnUnsavedChanges: PropTypes.bool,
|
||||
formComponents: PropTypes.object,
|
||||
|
||||
// callbacks
|
||||
submitCallback: PropTypes.func,
|
||||
|
|
|
@ -198,6 +198,7 @@ class FormComponent extends Component {
|
|||
*/
|
||||
getFormInput = () => {
|
||||
const inputType = this.getType();
|
||||
const FormComponents = this.props.formComponents;
|
||||
|
||||
// if input is a React component, use it
|
||||
if (typeof this.props.input === 'function') {
|
||||
|
@ -208,53 +209,53 @@ class FormComponent extends Component {
|
|||
|
||||
switch (inputType) {
|
||||
case 'text':
|
||||
return Components.FormComponentDefault;
|
||||
return FormComponents.FormComponentDefault;
|
||||
|
||||
case 'number':
|
||||
return Components.FormComponentNumber;
|
||||
return FormComponents.FormComponentNumber;
|
||||
|
||||
case 'url':
|
||||
return Components.FormComponentUrl;
|
||||
return FormComponents.FormComponentUrl;
|
||||
|
||||
case 'email':
|
||||
return Components.FormComponentEmail;
|
||||
return FormComponents.FormComponentEmail;
|
||||
|
||||
case 'textarea':
|
||||
return Components.FormComponentTextarea;
|
||||
return FormComponents.FormComponentTextarea;
|
||||
|
||||
case 'checkbox':
|
||||
return Components.FormComponentCheckbox;
|
||||
return FormComponents.FormComponentCheckbox;
|
||||
|
||||
case 'checkboxgroup':
|
||||
return Components.FormComponentCheckboxGroup;
|
||||
return FormComponents.FormComponentCheckboxGroup;
|
||||
|
||||
case 'radiogroup':
|
||||
return Components.FormComponentRadioGroup;
|
||||
return FormComponents.FormComponentRadioGroup;
|
||||
|
||||
case 'select':
|
||||
return Components.FormComponentSelect;
|
||||
return FormComponents.FormComponentSelect;
|
||||
|
||||
case 'selectmultiple':
|
||||
return Components.FormComponentSelectMultiple;
|
||||
return FormComponents.FormComponentSelectMultiple;
|
||||
|
||||
case 'datetime':
|
||||
return Components.FormComponentDateTime;
|
||||
return FormComponents.FormComponentDateTime;
|
||||
|
||||
case 'date':
|
||||
return Components.FormComponentDate;
|
||||
return FormComponents.FormComponentDate;
|
||||
|
||||
case 'date2':
|
||||
return Components.FormComponentDate2;
|
||||
return FormComponents.FormComponentDate2;
|
||||
|
||||
case 'time':
|
||||
return Components.FormComponentTime;
|
||||
return FormComponents.FormComponentTime;
|
||||
|
||||
case 'statictext':
|
||||
return Components.FormComponentStaticText;
|
||||
return FormComponents.FormComponentStaticText;
|
||||
|
||||
default:
|
||||
const CustomComponent = Components[this.props.input];
|
||||
return CustomComponent ? CustomComponent : Components.FormComponentDefault;
|
||||
const CustomComponent = FormComponents[this.props.input];
|
||||
return CustomComponent ? CustomComponent : FormComponents.FormComponentDefault;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -269,17 +270,20 @@ class FormComponent extends Component {
|
|||
return this.getFieldType() instanceof SimpleSchema
|
||||
}
|
||||
render() {
|
||||
|
||||
const FormComponents = this.props.formComponents;
|
||||
|
||||
if (this.props.intlInput) {
|
||||
return <Components.FormIntl {...this.props} />;
|
||||
return <FormComponents.FormIntl {...this.props} />;
|
||||
} else if (this.props.nestedInput) {
|
||||
if (this.isArrayField()) {
|
||||
return <Components.FormNestedArray {...this.props} errors={this.getErrors()} value={this.getValue()}/>;
|
||||
return <FormComponents.FormNestedArray {...this.props} errors={this.getErrors()} value={this.getValue()}/>;
|
||||
} else if (this.isObjectField()) {
|
||||
return <Components.FormNestedObject {...this.props} errors={this.getErrors()} value={this.getValue()}/>;
|
||||
return <FormComponents.FormNestedObject {...this.props} errors={this.getErrors()} value={this.getValue()}/>;
|
||||
}
|
||||
}
|
||||
return (
|
||||
<Components.FormComponentInner
|
||||
<FormComponents.FormComponentInner
|
||||
{...this.props}
|
||||
{...this.state}
|
||||
inputType={this.getType()}
|
||||
|
@ -290,6 +294,7 @@ class FormComponent extends Component {
|
|||
onChange={this.handleChange}
|
||||
clearField={this.clearField}
|
||||
formInput={this.getFormInput()}
|
||||
formComponents={FormComponents}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -38,12 +38,14 @@ class FormGroup extends PureComponent {
|
|||
|
||||
render() {
|
||||
|
||||
const FormComponents = this.props.formComponents;
|
||||
|
||||
return (
|
||||
<div className="form-section">
|
||||
{this.props.name === 'default' ? null : this.renderHeading()}
|
||||
<div className={classNames({ 'form-section-collapsed': this.state.collapsed && !this.hasErrors() })}>
|
||||
{this.props.fields.map(field => (
|
||||
<Components.FormComponent
|
||||
<FormComponents.FormComponent
|
||||
key={field.name}
|
||||
disabled={this.props.disabled}
|
||||
{...field}
|
||||
|
@ -56,6 +58,7 @@ class FormGroup extends PureComponent {
|
|||
clearFieldErrors={this.props.clearFieldErrors}
|
||||
formType={this.props.formType}
|
||||
currentUser={this.props.currentUser}
|
||||
formComponents={FormComponents}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
@ -19,6 +19,8 @@ class FormIntl extends PureComponent {
|
|||
|
||||
render() {
|
||||
|
||||
const FormComponents = this.props.formComponents;
|
||||
|
||||
// do not pass FormIntl's own value, inputProperties, and intlInput props down
|
||||
const properties = omit(this.props, 'value', 'inputProperties', 'intlInput', 'nestedInput');
|
||||
|
||||
|
@ -26,7 +28,7 @@ class FormIntl extends PureComponent {
|
|||
<div className="form-intl">
|
||||
{Locales.map((locale, i) => (
|
||||
<div className={`form-intl-${locale.id}`} key={locale.id}>
|
||||
<Components.FormComponent {...properties} label={this.props.getLabel(this.props.name, locale.id)} path={this.getLocalePath(i)} locale={locale.id} />
|
||||
<FormComponents.FormComponent {...properties} label={this.props.getLabel(this.props.name, locale.id)} path={this.getLocalePath(i)} locale={locale.id} />
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
|
|
@ -30,7 +30,8 @@ class FormNestedArray extends PureComponent {
|
|||
const value = this.getCurrentValue()
|
||||
// do not pass FormNested's own value, input and inputProperties props down
|
||||
const properties = _.omit(this.props, 'value', 'input', 'inputProperties', 'nestedInput');
|
||||
const { errors, path } = this.props;
|
||||
const { errors, path, formComponents } = this.props;
|
||||
const FormComponents = formComponents;
|
||||
// only keep errors specific to the nested array (and not its subfields)
|
||||
const nestedArrayErrors = errors.filter(error => error.path && error.path === path);
|
||||
const hasErrors = nestedArrayErrors && nestedArrayErrors.length;
|
||||
|
@ -42,7 +43,7 @@ class FormNestedArray extends PureComponent {
|
|||
{value.map(
|
||||
(subDocument, i) =>
|
||||
!this.isDeleted(i) && (
|
||||
<Components.FormNestedItem
|
||||
<FormComponents.FormNestedItem
|
||||
{...properties}
|
||||
key={i}
|
||||
itemIndex={i}
|
||||
|
@ -56,7 +57,7 @@ class FormNestedArray extends PureComponent {
|
|||
<Components.Button size="small" variant="success" onClick={this.addItem} className="form-nested-button">
|
||||
<Components.IconAdd height={12} width={12} />
|
||||
</Components.Button>
|
||||
{hasErrors ? <Components.FieldErrors errors={nestedArrayErrors} /> : null}
|
||||
{hasErrors ? <FormComponents.FieldErrors errors={nestedArrayErrors} /> : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -3,13 +3,14 @@ import PropTypes from 'prop-types';
|
|||
import { Components, registerComponent } from 'meteor/vulcan:core';
|
||||
|
||||
const FormNestedItem = ({ nestedFields, name, path, removeItem, itemIndex, ...props }, { errors }) => {
|
||||
const FormComponents = props.formComponents;
|
||||
const isArray = typeof itemIndex !== 'undefined';
|
||||
return (
|
||||
<div className="form-nested-item">
|
||||
<div className="form-nested-item-inner">
|
||||
{nestedFields.map((field, i) => {
|
||||
return (
|
||||
<Components.FormComponent
|
||||
<FormComponents.FormComponent
|
||||
key={i}
|
||||
{...props}
|
||||
{...field}
|
||||
|
|
|
@ -4,6 +4,7 @@ import { Components, registerComponent } from 'meteor/vulcan:core';
|
|||
|
||||
class FormNestedObject extends PureComponent {
|
||||
render() {
|
||||
const FormComponents = this.props.formComponents;
|
||||
//const value = this.getCurrentValue()
|
||||
// do not pass FormNested's own value, input and inputProperties props down
|
||||
const properties = _.omit(this.props, 'value', 'input', 'inputProperties', 'nestedInput');
|
||||
|
@ -15,8 +16,8 @@ class FormNestedObject extends PureComponent {
|
|||
<div className={`form-group row form-nested ${hasErrors ? 'input-error' : ''}`}>
|
||||
<label className="control-label col-sm-3">{this.props.label}</label>
|
||||
<div className="col-sm-9">
|
||||
<Components.FormNestedItem {...properties} path={`${this.props.path}`} />
|
||||
{hasErrors ? <Components.FieldErrors errors={nestedObjectErrors} /> : null}
|
||||
<FormComponents.FormNestedItem {...properties} path={`${this.props.path}`} />
|
||||
{hasErrors ? <FormComponents.FieldErrors errors={nestedObjectErrors} /> : null}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -52,8 +52,11 @@ class FormComponentInner extends PureComponent {
|
|||
showCharsRemaining,
|
||||
charsRemaining,
|
||||
renderComponent,
|
||||
formComponents,
|
||||
} = this.props;
|
||||
|
||||
const FormComponents = formComponents;
|
||||
|
||||
const hasErrors = errors && errors.length;
|
||||
|
||||
const inputName = typeof input === 'function' ? input.name : input;
|
||||
|
@ -72,7 +75,7 @@ class FormComponentInner extends PureComponent {
|
|||
<div className={inputClass}>
|
||||
{instantiateComponent(beforeComponent, properties)}
|
||||
<FormInput {...properties}/>
|
||||
{hasErrors ? <Components.FieldErrors errors={errors} /> : null}
|
||||
{hasErrors ? <FormComponents.FieldErrors errors={errors} /> : null}
|
||||
{this.renderClear()}
|
||||
{showCharsRemaining && (
|
||||
<div className={classNames('form-control-limit', { danger: charsRemaining < 10 })}>{charsRemaining}</div>
|
||||
|
|
Loading…
Add table
Reference in a new issue