Skip to content
This repository was archived by the owner on Apr 30, 2018. It is now read-only.

Tips & Tricks

yjaques edited this page Feb 5, 2015 · 6 revisions

Below are some tips and tricks from members in the community. Please feel free to add sections or make other changes here as needed!

Custom Templates

Scope Variables available

You have the following variables on your scope:

  • options - The data provided to configure the field
  • id - the id of the field, use this for the name of your ng-model
  • index - The index of the field the form is on (in ng-repeat)
  • value - A value getter/setter
  • form - the form controller the field is in
  • formControl - the ng-model controller of the field
  • result - the result of the form
  • fields - all the fields for the form

ng-form vs form

The formly-form directive uses ng-form under the hood. This allows you to nest forms which you cannot do with the regular form element. However, this also means that you're not able to use ng-submit on a formly-form either. This really stinks from an accessibility standpoint. However, you can augment ng-form itself to simulate this type of behavior like so:

(function() {
    'use strict';

    angular.module('app').directive('ngForm', ngForm);

    function ngForm() {
        return {
            restrict: 'E',
            link: function(scope, element, attrs) {
                var ngForm = scope.$eval(attrs.name);
                if (ngForm) {
                    ngForm.formlyDemoSubmit = function() {
                        if (ngForm.$invalid) {
                            return;
                        }
                        var context = scope.$parent;
                        ngForm.formlyDemoSubmitting = context.$eval(attrs.ngSubmit);
                        return ngForm.formlyDemoSubmitting;
                    };
                    element.on('keyup', function(event) {
                        if (event.which === 13 && attrs.ngSubmit) {
                            submitFormFromEvent(event);
                        }
                    });
                    var submitButton = angular.element(element[0].querySelectorAll('[type=submit]'));
                    if (submitButton.length === 1) {
                        submitButton.on('keyup', function(event) {
                            if (event.which === 32 || event.which === 13) {
                                submitFormFromEvent(event);
                            }
                        });
                        submitButton.on('click', submitFormFromEvent);
                    } else if (submitButton.length) {
                        throw new Error('Forms should only have one submit button');
                    }
                }

                function submitFormFromEvent(event) {
                    /* jshint -W030 */
                    event && event.preventDefault && event.preventDefault();
                    event && event.stopPropagation && event.stopPropagation();
                    ngForm.formlyDemoSubmit();
                    scope.$apply();
                }
            }
        };
    }
})();

Now you can use ng-submit on any formly-form and the button of type submit will submit the form as expected (for example):

<formly-form result="user" fields="userFields" ng-submit="save(user)">
  <button type="submit">Submit</button>
</formly-form>

Useful options

useNgIfToHide

If you've got performance issues with angular-formly give this option a try. Setting it to true will change fields with a hide=true to be hidden with ng-if instead of ng-hide meaning their watchers will be removed from the digest cycle (which is the leading cause of death for performance on angular pages).

Select Fields

Select fields can be tricky. Here are a few pointers: ##Values Although the examples show the select JSON looking like this:

 $scope.directory.form = [
{"key": "prefix", "type": "select", "default": 1, "label": "Prefix", options: [{ "name": "Mr."}, { "name": "Ms."}, { "name": "Dr."}]}
];

...as long as you have the "name" attribute, you can actually add as many attributes as you like to an option since Angular will ALWAYS use an index for the actual value and return the entire OBJECT back to your model onSelect, so for example you can do:

{"key": "prefix", "type": "select", "default": 1, "label": "Prefix", options: [{ "name": "Mister", "value": "Mr."}, { "name": "Miz", "value": "Ms."}, { "name": "Doctor", "value": "Dr."}]} ##Default Second important point, the "default" value will not give you a pre-selected item from the list. Again, Angular works from an MVVM principle, thus the important thing is to set the model value in the controller (don't hack the template and add ng-init, this is really not the recommended approach). So to get a default value, given the code block above and imaginging that our model is $scope.directory.data, you could do:

    $scope.directory.data.prefix= $scope.directory.form[0].options[0].value;

Then you will have your field set on the view as well since you just set the model.

Clone this wiki locally