-
Notifications
You must be signed in to change notification settings - Fork 399
Tips & Tricks
Below are some tips and tricks from members in the community. Please feel free to add sections or make other changes here as needed!
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 yourng-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
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>
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 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.