├── LICENSE
├── README.md
├── index.html
├── js
├── app.js
└── modules
│ └── promise-tracker.js
└── response.json
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 Juan Pablo Novillo
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AngularJS form example
2 |
3 | This repository contains a dummy contact form powered by AngularJS.
4 |
5 | See it in action at http://juampy72.github.io/angularjs_form
6 |
7 | There is a step by step tutorial on this form at [the Lullabot Blog](https://www.lullabot.com/blog/article/processing-forms-angularjs).
8 |
9 | ## Installation
10 |
11 | Simply clone this repository on a directory accessible from your local web server.
12 | Then, open index.html from a web browser.
13 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | AngularJS Form
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | AngularJs form
13 |
14 | This is an AngularJs based form. It uses a controller to handle form validation and submission.
15 | Find a step by step tutorial on this form at the Lullabot Blog .
16 |
17 |
18 |
19 |
20 |
Sending…
21 |
57 |
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/js/app.js:
--------------------------------------------------------------------------------
1 | /**
2 | * AngularJS module to process a form.
3 | */
4 | angular.module('myApp', ['ajoslin.promise-tracker'])
5 | .controller('help', function ($scope, $http, $log, promiseTracker, $timeout) {
6 | $scope.subjectListOptions = {
7 | 'bug': 'Report a Bug',
8 | 'account': 'Account Problems',
9 | 'mobile': 'Mobile',
10 | 'user': 'Report a Malicious User',
11 | 'other': 'Other'
12 | };
13 |
14 | // Inititate the promise tracker to track form submissions.
15 | $scope.progress = promiseTracker();
16 |
17 | // Form submit handler.
18 | $scope.submit = function(form) {
19 | // Trigger validation flag.
20 | $scope.submitted = true;
21 |
22 | // If form is invalid, return and let AngularJS show validation errors.
23 | if (form.$invalid) {
24 | return;
25 | }
26 |
27 | // Default values for the request.
28 | var config = {
29 | params : {
30 | 'callback' : 'JSON_CALLBACK',
31 | 'name' : $scope.name,
32 | 'email' : $scope.email,
33 | 'subjectList' : $scope.subjectList,
34 | 'url' : $scope.url,
35 | 'comments' : $scope.comments
36 | },
37 | };
38 |
39 | // Perform JSONP request.
40 | var $promise = $http.jsonp('response.json', config)
41 | .success(function(data, status, headers, config) {
42 | if (data.status == 'OK') {
43 | $scope.name = null;
44 | $scope.email = null;
45 | $scope.subjectList = null;
46 | $scope.url = null;
47 | $scope.comments = null;
48 | $scope.messages = 'Your form has been sent!';
49 | $scope.submitted = false;
50 | } else {
51 | $scope.messages = 'Oops, we received your request, but there was an error processing it.';
52 | $log.error(data);
53 | }
54 | })
55 | .error(function(data, status, headers, config) {
56 | $scope.progress = data;
57 | $scope.messages = 'There was a network error. Try again later.';
58 | $log.error(data);
59 | })
60 | .finally(function() {
61 | // Hide status messages after three seconds.
62 | $timeout(function() {
63 | $scope.messages = null;
64 | }, 3000);
65 | });
66 |
67 | // Track the request and show its progress to the user.
68 | $scope.progress.addPromise($promise);
69 | };
70 | });
71 |
--------------------------------------------------------------------------------
/js/modules/promise-tracker.js:
--------------------------------------------------------------------------------
1 | /*
2 | * promise-tracker - v2.0.0 - 2014-04-11
3 | * http://github.com/ajoslin/angular-promise-tracker
4 | * Created by Andy Joslin; Licensed under Public Domain
5 | */
6 |
7 | (function() {
8 |
9 | angular.module('ajoslin.promise-tracker', [])
10 |
11 | .provider('promiseTracker', function() {
12 | var trackers = {};
13 |
14 | this.$get = ['$q', '$timeout', function($q, $timeout) {
15 | function cancelTimeout(promise) {
16 | if (promise) {
17 | $timeout.cancel(promise);
18 | }
19 | }
20 |
21 | return function PromiseTracker(options) {
22 | //do new if user doesn't
23 | if (!(this instanceof PromiseTracker)) {
24 | return new PromiseTracker(options);
25 | }
26 |
27 | options = options || {};
28 |
29 | //Array of promises being tracked
30 | var tracked = [];
31 | var self = this;
32 |
33 | //Allow an optional "minimum duration" that the tracker has to stay active for.
34 | var minDuration = options.minDuration;
35 | //Allow a delay that will stop the tracker from activating until that time is reached
36 | var activationDelay = options.activationDelay;
37 |
38 | var minDurationPromise;
39 | var activationDelayPromise;
40 |
41 | self.active = function() {
42 | //Even if we have a promise in our tracker, we aren't active until delay is elapsed
43 | if (activationDelayPromise) {
44 | return false;
45 | }
46 | return tracked.length > 0;
47 | };
48 |
49 | self.tracking = function() {
50 | //Even if we aren't active, we could still have a promise in our tracker
51 | return tracked.length > 0;
52 | };
53 |
54 | self.destroy = self.cancel = function() {
55 | minDurationPromise = cancelTimeout(minDurationPromise);
56 | activationDelayPromise = cancelTimeout(activationDelayPromise);
57 | for (var i=tracked.length-1; i>=0; i--) {
58 | tracked[i].resolve();
59 | }
60 | tracked.length = 0;
61 | };
62 |
63 | //Create a promise that will make our tracker active until it is resolved.
64 | // @return deferred - our deferred object that is being tracked
65 | self.createPromise = function() {
66 | var deferred = $q.defer();
67 | tracked.push(deferred);
68 |
69 | //If the tracker was just inactive and this the first in the list of
70 | //promises, we reset our delay and minDuration
71 | //again.
72 | if (tracked.length === 1) {
73 | if (activationDelay) {
74 | activationDelayPromise = $timeout(function() {
75 | activationDelayPromise = cancelTimeout(activationDelayPromise);
76 | startMinDuration();
77 | }, activationDelay);
78 | } else {
79 | startMinDuration();
80 | }
81 | }
82 |
83 | deferred.promise.then(onDone(false), onDone(true));
84 |
85 | return deferred;
86 |
87 | function startMinDuration() {
88 | if (minDuration) {
89 | minDurationPromise = $timeout(angular.noop, minDuration);
90 | }
91 | }
92 |
93 | //Create a callback for when this promise is done. It will remove our
94 | //tracked promise from the array if once minDuration is complete
95 | function onDone(isError) {
96 | return function(value) {
97 | (minDurationPromise || $q.when()).then(function() {
98 | var index = tracked.indexOf(deferred);
99 | tracked.splice(index, 1);
100 |
101 | //If this is the last promise, cleanup the timeouts
102 | //for activationDelay
103 | if (tracked.length === 0) {
104 | activationDelayPromise = cancelTimeout(activationDelayPromise);
105 | }
106 | });
107 | };
108 | }
109 | };
110 |
111 | self.addPromise = function(promise) {
112 | var then = promise && (promise.then || promise.$then ||
113 | (promise.$promise && promise.$promise.then));
114 | if (!then) {
115 | throw new Error("promiseTracker#addPromise expects a promise object!");
116 | }
117 | var deferred = self.createPromise();
118 |
119 | //When given promise is done, resolve our created promise
120 | //Allow $then for angular-resource objects
121 | then(function success(value) {
122 | deferred.resolve(value);
123 | return value;
124 | }, function error(value) {
125 | deferred.reject(value);
126 | return $q.reject(value);
127 | });
128 |
129 | return deferred;
130 | };
131 | };
132 | }];
133 | });
134 |
135 | }());
--------------------------------------------------------------------------------
/response.json:
--------------------------------------------------------------------------------
1 | angular.callbacks._0({ status : "OK", info : 'This is a dummy response used for this example. Normally this would be a server side application that validates submitted data and performs the email submission.' })
2 |
--------------------------------------------------------------------------------