aboutsummaryrefslogtreecommitdiffstats
path: root/src/directive/form.js
diff options
context:
space:
mode:
authorMisko Hevery2012-03-23 14:03:24 -0700
committerMisko Hevery2012-03-28 11:16:35 -0700
commit2430f52bb97fa9d682e5f028c977c5bf94c5ec38 (patch)
treee7529b741d70199f36d52090b430510bad07f233 /src/directive/form.js
parent944098a4e0f753f06b40c73ca3e79991cec6c2e2 (diff)
downloadangular.js-2430f52bb97fa9d682e5f028c977c5bf94c5ec38.tar.bz2
chore(module): move files around in preparation for more modules
Diffstat (limited to 'src/directive/form.js')
-rw-r--r--src/directive/form.js267
1 files changed, 0 insertions, 267 deletions
diff --git a/src/directive/form.js b/src/directive/form.js
deleted file mode 100644
index b6d3f4be..00000000
--- a/src/directive/form.js
+++ /dev/null
@@ -1,267 +0,0 @@
-'use strict';
-
-
-var nullFormCtrl = {
- $addControl: noop,
- $removeControl: noop,
- $setValidity: noop,
- $setDirty: noop
-}
-
-/**
- * @ngdoc object
- * @name angular.module.ng.$compileProvider.directive.form.FormController
- *
- * @property {boolean} $pristine True if user has not interacted with the form yet.
- * @property {boolean} $dirty True if user has already interacted with the form.
- * @property {boolean} $valid True if all of the containg forms and controls are valid.
- * @property {boolean} $invalid True if at least one containing control or form is invalid.
- *
- * @property {Object} $error Is an object hash, containing references to all invalid controls or
- * forms, where:
- *
- * - keys are validation tokens (error names) — such as `REQUIRED`, `URL` or `EMAIL`),
- * - values are arrays of controls or forms that are invalid with given error.
- *
- * @description
- * `FormController` keeps track of all its controls and nested forms as well as state of them,
- * such as being valid/invalid or dirty/pristine.
- *
- * Each {@link angular.module.ng.$compileProvider.directive.form form} directive creates an instance
- * of `FormController`.
- *
- */
-FormController.$inject = ['$element', '$attrs'];
-function FormController(element, attrs) {
- var form = this,
- parentForm = element.parent().controller('form') || nullFormCtrl,
- invalidCount = 0, // used to easily determine if we are valid
- errors = form.$error = {};
-
- // init state
- form.$name = attrs.name;
- form.$dirty = false;
- form.$pristine = true;
- form.$valid = true;
- form.$invalid = false;
-
- parentForm.$addControl(form);
-
- // Setup initial state of the control
- element.addClass(PRISTINE_CLASS);
- toggleValidCss(true);
-
- // convenience method for easy toggling of classes
- function toggleValidCss(isValid, validationErrorKey) {
- validationErrorKey = validationErrorKey ? '-' + snake_case(validationErrorKey, '-') : '';
- element.
- removeClass((isValid ? INVALID_CLASS : VALID_CLASS) + validationErrorKey).
- addClass((isValid ? VALID_CLASS : INVALID_CLASS) + validationErrorKey);
- }
-
- form.$addControl = function(control) {
- if (control.$name && !form.hasOwnProperty(control.$name)) {
- form[control.$name] = control;
- }
- };
-
- form.$removeControl = function(control) {
- if (control.$name && form[control.$name] === control) {
- delete form[control.$name];
- }
- forEach(errors, cleanupControlErrors, control);
- };
-
- form.$setValidity = function(validationToken, isValid, control) {
- if (isValid) {
- cleanupControlErrors(errors[validationToken], validationToken, control);
-
- if (!invalidCount) {
- toggleValidCss(isValid);
- form.$valid = true;
- form.$invalid = false;
- }
- } else {
- if (!invalidCount) {
- toggleValidCss(isValid);
- }
- addControlError(validationToken, control);
-
- form.$valid = false;
- form.$invalid = true;
- }
- };
-
- form.$setDirty = function() {
- element.removeClass(PRISTINE_CLASS).addClass(DIRTY_CLASS);
- form.$dirty = true;
- form.$pristine = false;
- };
-
- function cleanupControlErrors(queue, validationToken, control) {
- if (queue) {
- control = control || this; // so that we can be used in forEach;
- arrayRemove(queue, control);
- if (!queue.length) {
- invalidCount--;
- errors[validationToken] = false;
- toggleValidCss(true, validationToken);
- parentForm.$setValidity(validationToken, true, form);
- }
- }
- }
-
- function addControlError(validationToken, control) {
- var queue = errors[validationToken];
- if (queue) {
- if (includes(queue, control)) return;
- } else {
- errors[validationToken] = queue = [];
- invalidCount++;
- toggleValidCss(false, validationToken);
- parentForm.$setValidity(validationToken, false, form);
- }
- queue.push(control);
- }
-}
-
-
-/**
- * @ngdoc directive
- * @name angular.module.ng.$compileProvider.directive.ng-form
- * @restrict EAC
- *
- * @description
- * Nestable alias of {@link angular.module.ng.$compileProvider.directive.form `form`} directive. HTML
- * does not allow nesting of form elements. It is useful to nest forms, for example if the validity of a
- * sub-group of controls needs to be determined.
- *
- * @param {string=} ng-form|name Name of the form. If specified, the form controller will be published into
- * related scope, under this name.
- *
- */
-
- /**
- * @ngdoc directive
- * @name angular.module.ng.$compileProvider.directive.form
- * @restrict E
- *
- * @description
- * Directive that instantiates
- * {@link angular.module.ng.$compileProvider.directive.form.FormController FormController}.
- *
- * If `name` attribute is specified, the form controller is published onto the current scope under
- * this name.
- *
- * # Alias: {@link angular.module.ng.$compileProvider.directive.ng-form `ng-form`}
- *
- * In angular forms can be nested. This means that the outer form is valid when all of the child
- * forms are valid as well. However browsers do not allow nesting of `<form>` elements, for this
- * reason angular provides {@link angular.module.ng.$compileProvider.directive.ng-form `ng-form`} alias
- * which behaves identical to `<form>` but allows form nesting.
- *
- *
- * # CSS classes
- * - `ng-valid` Is set if the form is valid.
- * - `ng-invalid` Is set if the form is invalid.
- * - `ng-pristine` Is set if the form is pristine.
- * - `ng-dirty` Is set if the form is dirty.
- *
- *
- * # Submitting a form and preventing default action
- *
- * Since the role of forms in client-side Angular applications is different than in classical
- * roundtrip apps, it is desirable for the browser not to translate the form submission into a full
- * page reload that sends the data to the server. Instead some javascript logic should be triggered
- * to handle the form submission in application specific way.
- *
- * For this reason, Angular prevents the default action (form submission to the server) unless the
- * `<form>` element has an `action` attribute specified.
- *
- * You can use one of the following two ways to specify what javascript method should be called when
- * a form is submitted:
- *
- * - ng-submit on the form element (add link to ng-submit)
- * - ng-click on the first button or input field of type submit (input[type=submit])
- *
- * To prevent double execution of the handler, use only one of ng-submit or ng-click. This is
- * because of the following form submission rules coming from the html spec:
- *
- * - If a form has only one input field then hitting enter in this field triggers form submit
- * (`ng-submit`)
- * - if a form has has 2+ input fields and no buttons or input[type=submit] then hitting enter
- * doesn't trigger submit
- * - if a form has one or more input fields and one or more buttons or input[type=submit] then
- * hitting enter in any of the input fields will trigger the click handler on the *first* button or
- * input[type=submit] (`ng-click`) *and* a submit handler on the enclosing form (`ng-submit`)
- *
- * @param {string=} name Name of the form. If specified, the form controller will be published into
- * related scope, under this name.
- *
- * @example
- <doc:example>
- <doc:source>
- <script>
- function Ctrl($scope) {
- $scope.userType = 'guest';
- }
- </script>
- <form name="myForm" ng-controller="Ctrl">
- userType: <input name="input" ng-model="userType" required>
- <span class="error" ng-show="myForm.input.$error.REQUIRED">Required!</span><br>
- <tt>userType = {{userType}}</tt><br>
- <tt>myForm.input.$valid = {{myForm.input.$valid}}</tt><br>
- <tt>myForm.input.$error = {{myForm.input.$error}}</tt><br>
- <tt>myForm.$valid = {{myForm.$valid}}</tt><br>
- <tt>myForm.$error.REQUIRED = {{!!myForm.$error.REQUIRED}}</tt><br>
- </form>
- </doc:source>
- <doc:scenario>
- it('should initialize to model', function() {
- expect(binding('userType')).toEqual('guest');
- expect(binding('myForm.input.$valid')).toEqual('true');
- });
-
- it('should be invalid if empty', function() {
- input('userType').enter('');
- expect(binding('userType')).toEqual('');
- expect(binding('myForm.input.$valid')).toEqual('false');
- });
- </doc:scenario>
- </doc:example>
- */
-var formDirectiveDir = {
- name: 'form',
- restrict: 'E',
- controller: FormController,
- compile: function() {
- return {
- pre: function(scope, formElement, attr, controller) {
- if (!attr.action) {
- formElement.bind('submit', function(event) {
- event.preventDefault();
- });
- }
-
- var parentFormCtrl = formElement.parent().controller('form'),
- alias = attr.name || attr.ngForm;
-
- if (alias) {
- scope[alias] = controller;
- }
- if (parentFormCtrl) {
- formElement.bind('$destroy', function() {
- parentFormCtrl.$removeControl(controller);
- if (alias) {
- scope[alias] = undefined;
- }
- extend(controller, nullFormCtrl); //stop propagating child destruction handlers upwards
- });
- }
- }
- };
- }
-};
-
-var formDirective = valueFn(formDirectiveDir);
-var ngFormDirective = valueFn(extend(copy(formDirectiveDir), {restrict: 'EAC'}));