-
Notifications
You must be signed in to change notification settings - Fork 393
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
nameof 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.