Skip welcome & menu and move to editor
Welcome to JS Bin
Load cached copy from
 
<!DOCTYPE html>
<html>
  <head>
    <script src="//code.jquery.com/jquery-2.1.1.min.js"></script>
    <!-- Twitter bootstrap -->
    <link href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" rel="stylesheet">
    <!-- apiCheck is used by formly to validate its api -->
    <script src="//rawgit.com/kentcdodds/apiCheck.js/master/dist/api-check.min.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular.js"></script>
    <script src="//ajax.googleapis.com/ajax/libs/angularjs/1.3.11/angular-messages.min.js"></script>
    <script src="//rawgit.com/formly-js/angular-formly/master/dist/formly.js"></script>
    <title>Angular Formly Example</title>
  </head>
  <body ng-app="formlyExample" ng-controller="MainCtrl as vm">
    <div>
      <h1>angular-formly example: {{vm.exampleTitle}}</h1>
      <div>
        This was originally created based on <a href="https://twitter.com/kentcdodds/status/601765588533317632">this tweet</a>.
        It describes some of the nuances of <code>&lt;form&gt;</code>, <code>&lt;ng-form&gt;</code>, and <code>&lt;formly-form&gt;</code>
      </div>
      <hr />
      <div>
        Below is an example of using the formly <code>setTemplateWrapper</code> feature to keep templates consistent.
        In this example, we add validation (using the <code>validators</code> api in combination with angular-messages)
        and we only need to add that in one place and it's exactly the same for all formly types.
        <br />
        This also demos how to specify different template wrappers for different types. Generally this is useful when you
        have multiple types using the same template wrapper, but it can be useful if you want to use the formly template without the wrapper
        (also demonstrated).
      </div>
      <hr>
      <strong>Using <code>form</code> attribute on a <code>&lt;formly-form&gt;</code> and putting <code>ng-submit</code> on a parent <code>&lt;form&gt;</code> will not work because the parent form is the one submitted, not the formly-form.</strong>
      <pre>exampleForm1.$submitted: {{ exampleForm1.$submitted | json }}</pre>
      
      <form ng-submit="vm.onSubmit()" novalidate>
        <formly-form model="vm.model" fields="vm.fields" form="exampleForm1">
          <button type="submit" class="btn btn-primary submit-button">Submit won't update form $submitted</button>
        </formly-form>
      </form>
      
      <hr/>
      
      <strong>It's just like using the <code>name</code> attribute on a nested <code>&lt;ng-form&gt;</code> with <code>ng-submit</code> on a parent <code>&lt;form&gt;</code></strong>
      <pre>exampleForm2.$submitted: {{ exampleForm2.$submitted | json }}</pre>
      
      <form ng-submit="vm.onSubmit()" novalidate>
        <ng-form name="exampleForm2">
          <button type="submit" class="btn btn-primary submit-button">Submit won't update form $submitted</button>
        </ng-form>
      </form>
      
      
      <hr/>
      
      <strong>But if you put the <code>name</code> on the same <code>&lt;form&gt;</code> as the <code>ng-submit</code> is on, then <code>$submitted</code> gets updated as expected</strong>
      
      <pre>exampleForm3.$submitted: {{ exampleForm3.$submitted | json }}</pre>
      
      <form ng-submit="vm.onSubmit()" novalidate name="exampleForm3">
        <formly-form model="vm.model" fields="vm.fields">
          <button type="submit" class="btn btn-primary submit-button">Submit will update form $submitted</button>
        </formly-form>
      </form>
      
      <hr/>
      
      <strong>But if you try to put an <code>ng-submit</code> on an <code>&lt;ng-form&gt;</code> the statement wont even be called</strong>
      <pre>exampleForm4.$submitted: {{ exampleForm4.$submitted | json }}</pre>
      <div>
        <ng-form name="exampleForm4" ng-submit="vm.onSubmit()">
          <button type="submit" class="btn btn-primary submit-button">Submit won't even get called</button>
        </ng-form>
      </div>
      
      <hr/>
      
      <strong>Which is why an <code>ng-submit</code> on a <code>&lt;formly-form&gt;</code> with a <code>form</code> doesn't work either (because it actually just replaces itself with an <code>&lt;ng-form&gt;</code></strong>
      <pre>exampleForm5.$submitted: {{ exampleForm5.$submitted | json }}</pre>
      <div>
        <formly-form form="exampleForm5" ng-submit="vm.onSubmit()" model="vm.model" fields="vm.fields">
          <button type="submit" class="btn btn-primary submit-button">Submit won't work here either</button>
        </formly-form>
      </div>
      
      <hr/>
      
      <strong>This is due to limitations with <code>&lt;ng-form&gt;</code></strong>.
      
      <hr/>
      
      <strong>Solution 1: use <code>name</code> attribute on the parent <code>&lt;form&gt;</code> and pass the same value to the <code>&lt;formly-form&gt;</code>'s <code>form</code> attribute. <code>&lt;formly-form&gt;</code> will then use that exact same form (rather than the one it creates on its own)</strong>
      
      <pre>exampleForm6.$submitted: {{ exampleForm6.$submitted | json }}</pre>
      
      <form ng-submit="vm.onSubmit()" novalidate name="exampleForm6">
        <formly-form model="vm.model" fields="vm.fields" form="exampleForm6">
          <button type="submit" class="btn btn-primary submit-button">Submit will update form $submitted</button>
        </formly-form>
      </form>
      
      <strong>Solution 2: use <code>name</code> attribute on the parent <code>&lt;form&gt;</code> and don't specify the same name in the <code>form</code> attribute on the <code>&lt;formly-form&gt;</code> (because you probably don't even need the <code>form</code> attribute).</strong>
      
      <pre>exampleForm7.$submitted: {{ exampleForm7.$submitted | json }}</pre>
      
      <form ng-submit="vm.onSubmit()" novalidate name="exampleForm7">
        <formly-form model="vm.model" fields="vm.fields">
          <button type="submit" class="btn btn-primary submit-button">Submit will update form $submitted</button>
        </formly-form>
      </form>
      
      <hr />
      
      <strong>Solution 3: Specify <code>"form"</code> as the <code>root-el</code> attribute on the <code>&lt;formly-form&gt;</code> which will have it use a <code>&lt;form&gt;</code> instead of an <code>&lt;ng-form&gt;</code>. Note: HTML doesn't allow nesting of <code>&lt;form&gt;</code>s. Which is why <code>&lt;ng-form&gt;</code> exists in the first place and why angular-formly uses it. You have been warned</strong>
      
      <pre>exampleForm8.$submitted: {{ exampleForm8.$submitted | json }}</pre>
      
      <formly-form model="vm.model" fields="vm.fields" ng-submit="vm.onSubmit()" form="exampleForm8" root-el="form">
        <button type="submit" class="btn btn-primary submit-button">Submit will update form $submitted</button>
      </formly-form>
      
      <hr />
      
      <strong>Solution 3: Modify <a href="https://gist.github.com/kentcdodds/47c76d3e579ae10b9c2d">this gist</a> to add support for <code>&lt;ng-form</code> which will make it work for <code>&lt;formly-form&gt;</code> as well. To be honest, this is probably not the best way to go about it though...</strong>
      
      <pre>exampleForm9.$submitted: {{ exampleForm8.$submitted | json }}</pre>
      
      <formly-form model="vm.model" fields="vm.fields" ng-submit="vm.onSubmit()" form="exampleForm9">
        <button type="submit" class="btn btn-primary submit-button">Submit will update form $submitted (when you modify the gist and add it to your project)</button>
      </formly-form>
      
      
      <h2>Model</h2>
      <pre>{{vm.model | json}}</pre>
      <h2>Fields <small>(note, functions are not shown)</small></h2>
      <pre>{{vm.originalFields | json}}</pre>
    </div>
    <div style="margin-top:30px">
      <small>
        This is an example for the
        <a href="https://formly-js.github.io/angular-formly">angular-formly</a>
        project made with ♥ by
        <strong>
          <span ng-if="!vm.author.name || !vm.author.url">
            {{vm.author.name || 'anonymous'}}
          </span>
          <a ng-if="vm.author.url" ng-href="{{::vm.author.url}}">
            {{vm.author.name}}
          </a>
        </strong>
        <br />
        This example is running angular version "{{vm.env.angularVersion}}" and formly version "{{vm.env.formlyVersion}}"
      </small>
    </div>
    <!-- Put custom templates here -->
    <script type="text/ng-template" id="validation.html">
      <div ng-message="required">This field is required</div>
      <div ng-message="minlength">Too short</div>
      <div ng-message="maxlength">Too long</div>
      <div ng-message="email">Invalid email address</div>
    </script>
    
    <script type="text/ng-template" id="input-template.html">
      <input type="{{options.templateOptions.type || 'text'}}"
           class="form-control"
           id="{{id}}"
           formly-dynamic-name="id"
           formly-custom-validation="options.validators"
           placeholder="{{options.templateOptions.placeholder}}"
           aria-describedby="{{id}}_description"
           ng-required="options.templateOptions.required"
           ng-disabled="options.templateOptions.disabled"
           ng-model="model[options.key]">
    </script>
    <script type="text/ng-template" id="checkbox-template.html">
      <input type="checkbox"
             id="{{id}}"
             formly-dynamic-name="id"
             formly-custom-validation="options.validators"
             aria-describedby="{{id}}_description"
             ng-required="options.templateOptions.required"
             ng-disabled="options.templateOptions.disabled"
             ng-model="model[options.key]">
      {{options.templateOptions.label || 'Checkbox'}}
      {{options.templateOptions.required ? '*' : ''}}
    </script>
  </body>
</html>
 
body {
  margin: 20px
}
.formly-field {
  margin-bottom: 20px;
}
.validation {
  position: absolute;
  font-size: .8em;
  color: #a94442;
}
.formly-template-wrapper {
  position: relative;
}
 
/* global angular */
(function() {
  'use strict';
  var app = angular.module('formlyExample', ['formly']);
  
  app.controller('MainCtrl', function MainCtrl(formlyVersion) {
    var vm = this;
    // funcation assignment
    vm.onSubmit = onSubmit;
    // variable assignment
    vm.author = { // optionally fill in your info below :-)
      name: 'Kent C. Dodds',
      url: 'https://twitter.com/kentcdodds'
    };
    vm.exampleTitle = 'how $submitted works'; // add this
    vm.env = {
      angularVersion: angular.version.full,
      formlyVersion: formlyVersion
    };
    vm.model = {};
    vm.fields = [];
    vm.originalFields = angular.copy(vm.fields);
    // function definition
    function onSubmit() {
      alert('Submitted!');
    }
  });
})();
Output

You can jump to the latest bin by adding /latest to your URL

Dismiss x
public
Bin info
kentcdoddspro
0viewers