ember-form-master-2000 v3.4.1
NOTE
This project is in the process of moving towards Ember 2.1. There is still some work to be done, so please have patience.
Installation
This is an ember-cli addon and can be installed using npm:
npm install --save-dev ember-form-master-2000Demo
You can see the basic dummy app here:
Overview
Ember Form Master 2000 is an extensible library for creating forms in Ember. The library comes out of the box with the standard form components you would expect and it is easy to add more custom components as needed.
FM2000's primary entry point is the fm-field component. This is
used to render a form field to the page. Even when you are making custom
components you will still use fm-field to render them.
Every time a field is rendered, it renders a display and a widget.
displays are responible for the layout and css formatting of your form
field. For example, using different displays you could opt to
render a field using horizontal form style or a stacked form style.
widgets are responsible for encapulsating the actual component
that is manipulated. There are built in widgets for things like
input and textarea but you could add a custom date picker widget or
a fancy autocomplete widget. To learn more about creating custom displays
and widgets see the Extending Form Master below.
Validation
Currently FM2000 is all about rendering interactive forms in a standardized way with a concise and extensible syntax. FM2000 is not about doing form validation or managing CRUD logic. We may consider adding this functionality in the future but it will be as a separate layer from the existing components which are purely responsible for form display.
Built-In Components
The following is the basic API for Ember 2.3+. The hash helper that
is used below is not present in Ember 2.0-2.2. We are currently still supporting
setting the widgetAttrs values for the default widgets directly on the
fm-field component. For those versions just
specifiy widgetAttrs directly on the the component. The supported
attributes for this are listed in the WIDGET_ATTR_ALIASES constant in
addon/components/fm-field.js.
{{#fm-form action='submit'}}
{{fm-field label='First Name'
value=model.exampleModel.first_name
errors=model.exampleModel.errors.first_name
placeholder='Foo'
}}
{{fm-field label='Last Name'
value=model.exampleModel.last_name
errors=model.exampleModel.errors.last_name
placeholder='Bar'
}}
{{fm-field
label='Write an Essay'
type='textarea'
value=model.exampleModel.essay
errors=model.exampleModel.errors.essay
rows='6'
helptext='Make sure its good!'
data-test='master-2000'
}}
{{fm-field
label='Choose Something'
type='select'
content=model.selectOptions
optionValuePath='value'
optionLabelPath='label'
prompt='Select Something'
value=model.exampleModel.language
action=(action (mut model.exampleModel.language))
errors=model.exampleModel.errors.language
}}
{{fm-field
widget='checkbox'
label='Are you awesome?'
value=model.exampleModel.isAwesome
errors=model.exampleModel.errors.isAwesome
}}
{{fm-field
widget='radio-group'
label='Choose the best language'
name='bestLanguage'
content=model.radioOptions
optionValuePath='value'
optionLabelPath='label'
value=model.exampleModel.bestLanguage
errors=model.exampleModel.errors.bestLanguage
}}
{{fm-submit value='Submit the Form' disabled=model.disableSubmit}}
{{/fm-form}}Extending Form Master
There are two ways to extend form-master's built in functionality.
Widgets
Widgets are responsible for creating a UI object to manipulate some
data. Form-master provides some builtin widgets such as select, textarea and
radio-group. Note that some widgets are interchangeable for the same
type of data. Both a textarea and input work well for manipulating
a string attribute. Similarly, a selection from a predefined list could
be done with either a select or a radio-group widget.
You can easily override any of the existing widgets to augment or modify their functionality.
Widgets should do as little as possible to affect their appearance.
They should not specify css classes and should contain as little dom in
their templates as is necessary for them to function. For an example of
this, look at how fm-widgets/checkbox contains only the checkbox
element itself and the label and surrounding divs are in the
fm-displays/checkbox component.
You can also create your own custom widgets. For instance, you may want to
create an autocompleting text input. This would be easily done by creating
a new component called fm-widgets/autocomplete.
You would then be able to create a field
with an autocomplete widget as follows:
{{fm-field
widget='autocomplete'
value=value
widgetAttrs=(hash
choices=autocompleteChoices
placeholder=placeholder
)
}}The fm-field component will take care of adding labels, errors and
formatting classes around your autocomplete widget. Meanwhile your
autocomplete widget can focus solely on adding the extra autocomplete
functionality you want.
You can create custom form widgets easily. Simply create a new
component named as fm-widgets/<your widget name>. A widget will
receive the following attrs:
value: the current value of the input.action(optional): action to call with a new value chosen through user interaction with the widget. If you do not want to support actions-up/data-down design you can modifyvaluedirectly and ignoreaction.widgetAttrs: an Ember.Object which is used as a vessel to pass any custom values for your widget. For instance a select, widget would look for the choices, labelField and valueField properties in thewidgetAttrsproperty.onUserInteraction: your custom widget needs to call this action whenever it is manipulated. This letsfm-fieldknow when it should show errors on the form field.classNames: allows thefm-field'sdisplay component to add certain standard css classes.
Displays
Displays let you customize the aesthetics of a form field. For
instance, you may want to create a display where the fields label and
inputs appear in rows. You could do this by creating a component
called fm-displays/horizontal. Your
templates/components/fm-displays/horizontal.hbs might look like this:
<div class="{{styles.wrapperClass}}">
<label for="{{forAttribute}}" class="col-sm-2 {{styles.labelClass}}">
{{label}}
</label>
<div class="col-sm-10">
{{yield inputClasses}}
</div>
{{#if visibleErrors.length}}
<span class="{{styles.errortextClass}}">
{{visibleErrors.firstObject}}
</span>
{{/if}}
{{#if helptext}}
<span class="{{styles.helptextClass}}">
{{helptext}}
</span>
{{/if}}
</div>This widget will be included wherever you place the yield statement.
The inputClasses attribute is passed to the yield statement to
specify classes that should be applied to the widget itself.
You can now use this display anywhere in your application by simply specifying
the layout when creating an fm-field:
{{fm-field
display='horizontal'
widget='input'
value=myValue
errors=errors
placholder=placehodler
}}Note how we defer to styles property for class names where possible.
This ties in the fm-config service which provides easy configuration of
form classes on a global basis.
The best place to start for creating a display is to look at
fm-displays/default.hbs.
Errors
Displaying validation errors is a core requirement for any form library.
To keep things simple, you must explicitly tell fm-fields what errors
should be displayed. When provided an array of errors,
fm-field will display the first error.
var model = Ember.Object.create();
model.set('errors', Ember.Object.create({first_name: ['Required', 'Too short']}));
{{fm-field type='text' value=model.first_name errors=model.errors.first_name}}By default, fm-field displays any error that is included in the
errors property. If you do not want errors to be displayed until a
fm-field has been manipulated for the first time, set the
showErrorsByDefault property in the fm-config service to false.
With this change, fm-field will only display errors when it has been
notified by its widget that the widget has received user interaction.
If you are using the fm-form wrapper component and fm-submit then
clicking the fm-submit button will also cause errors to display.
Minor Customizations
If you need to make minor adjustments to classnames of the elements, you can easily override the default initializer with your own. The default initializer can be found here, which imports the default configuration from the addon directory.
Demo App
You can see a more holistic example by looking at the Dummy app that we use to test against. The index.hbs template and the application route are of particular interest.
4 years ago
4 years ago
4 years ago
4 years ago
7 years ago
7 years ago
7 years ago
7 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
9 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
10 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago
11 years ago