Form Extensions API Docs

johnculviner edited this page Oct 6, 2014 · 12 revisions

Intro

Form extensions is built to be extremely configurable

  • Generally Bootstrap markup is being demoed in the examples because it is common but you are free to use whatever you want!
  • Many directives are actually a composite (or 'macro' if you will) for several directives which each can be specified independently and overridden if desired
  • All directives that do DOM manipulation are customizable on both a per instance and global basis via a provider model.

Note: these docs need to be updated with new features (pretty much everything is configurable with the strategy pattern indicated on aa-label) but everything mentioned here still works


Directives

aa-field-group

aa-field-group is the most intensive of all the directive "macros". Here is an example of roughly what it does (the generated markup is functionally like below but NOT literally)

Example

Initial HTML

<input type="email" aa-field-group="person.email" required />

Functional HTML

<div class="form-group">
    <label for="email" class="col-sm-2 control-label">
        Email *
    </label>
    <div class="col-sm-3">
        <input type="email" required class="form-control" ng-model="person.email" name="email" id="email">
        <div class="validation-error" ng-show="(exampleForm.email.$dirty || invalidSubmitAttempt)&& exampleForm.email.$error.required">
            Email is required.
        </div>
        <div class="validation-error" ng-show="(exampleForm.email.$dirty || invalidSubmitAttempt) && exampleForm.email.$error.email">
            Email must be a valid email address.
        </div>
    </div>
</div>

API

<FORM-ELEMENT aa-field-group="BINDING-EXPRESION" 
  [aa-field-group-strategy="STRATEGY-NAME"]
  [aa-label="CUSTOM-LABEL-TEXT"]
  [aa-label-strategy="STRATEGY-NAME"]
  [aa-val-msg="STRATEGY-NAME"]
>

Auto Generation

aa-field-group is a macro that actually produces the following markup and directives 'under the hood' using the default bootstrap3InlineForm fieldGroupStrategy.

<div class="form-group">
    <div class="col-sm-3">
        <FORM-ELEMENT aa-field="BINDING-EXPRESION">
    </div>
</div>

This isn't terribly interesting but what it does create is surrounding markup and an aa-field which does a whole lot more work.


aa-field

aa-field in a nutshell can be used to automatically generate almost everything that is required to produce and label a field except any surrounding "form group" markup (if applicable). For example:

Example

Initial HTML

<div class="form-group">
    <div class="col-sm-3">
        <input type="text" class="form-control" aa-field="person.firstName" required ng-minlength="2" ng-maxlength="30"/>
    </div>
</div>

Functional HTML

<div class="form-group">
    <label for="firstName" class="col-sm-2 control-label">
        First Name *
    </label>
    <div class="col-sm-3">
        <input type="text" required class="form-control" ng-model="person.firstName" name="firstName" id="firstName">

        <div class="validation-error" ng-show="(exampleForm.firstName.$dirty || invalidSubmitAttempt) && exampleForm.firstName.$error.required">
            First Name is required.
        </div>
        <div class="validation-error" ng-show="(exampleForm.firstName.$dirty || invalidSubmitAttempt) && exampleForm.firstName.$error.maxlength">
            First name must be less than 30 characters.
        </div>
        <div class="validation-error" ng-show="(exampleForm.firstName.$dirty || invalidSubmitAttempt) && exampleForm.firstName.$error.minlength">
            First Name must be greater than 2 characters.
        </div>
    </div>
</div>

API

<FORM-ELEMENT aa-field="BINDING-EXPRESION" 
  [aa-label="CUSTOM-LABEL-TEXT"]
  [aa-label-strategy="OPTIONAL-STRATEGY-NAME"]
  [aa-val-msg="OPTIONAL-STRATEGY-NAME"]
>

Auto Generation

aa-field is a macro that actually produces the following markup and directives 'under the hood':

  • A name for the element if it doesn't already exist (required by Angular)
  • A type="text" if nothing else is specified so CSS selectors looking for this work properly while allowing for tearse markup
  • An aa-label directive who's label text looks like this (de camel casing etc.): foo.bar.firstName => First Name
  • An aa-val-msg directive using the default strategy to produce inline error messages when the field is invalid

This element markup

<FORM-ELEMENT aa-field="person.firstName" >

Generates this element markup

<FORM-ELEMENT ng-model="person.firstName" name="firstName" aa-label="First Name" aa-val-msg >

aa-label

aa-label automatically generates labels in the appropriate position using a labelStrategy. It may be used by it's self but is often automatically generated by aa-field-group or aa-field directives. If aa-label is used in conjunction with the aforementioned directives it will override/customize the output

Provider model

The output of aa-label can be modified globally by registering new label strategies:

aaFormExtensionsProvider.labelStrategies.myCustom = function (element, labelText, isRequired) {
//...
}

Or setting a new/existing strategy to be default:

aaFormExtensionsProvider.defaultLabelStrategy = "myCustom";

Selecting a non-default label strategy can be done on a per-instance basis using aa-label-strategy

<FORM-ELEMENT aa-label="Foo Bar" aa-label-strategy="customPerInstanceStrategy" required />

Example

Initial HTML

<ELEMENT-A>
    <ELEMENT-B>
        <FORM-ELEMENT aa-label="Foo Bar" required />
    </ELEMENT-B>
</ELEMENT-A>

Subsequent HTML

<ELEMENT-A>
    <label for="3eb12ae8-3300-4ea0-bee4-c11915f96f62" class="col-sm-2 control-label">Foo Bar *</label>
    <ELEMENT-B>
        <FORM-ELEMENT id="3eb12ae8-3300-4ea0-bee4-c11915f96f62" aa-label="Foo Bar" required />
    </ELEMENT-B>
</ELEMENT-A>

API

<FORM-ELEMENT aa-label="LABEL-TEXT" 
  [aa-label-strategy="OPTIONAL-STRATEGY-NAME"]
  [required]
  [id="ONE_WILL_BE_GENERATED_IF_NOT_SPECIFIED"]
>