├── .gitignore
├── LICENSE
├── README.md
├── bower.json
├── demo
├── app.js
├── form-template.js
└── index.html
└── dynamic-forms.js
/.gitignore:
--------------------------------------------------------------------------------
1 | # First line ignored?
2 | node_modules
3 | bower_components
4 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013-2014 Dan Hunsaker
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, 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,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | angular-dynamic-forms
2 | =====================
3 |
4 | [](https://gitter.im/danhunsaker/angular-dynamic-forms?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
5 | Build Forms in AngularJS From Nothing But JSON
6 |
7 | Uses the MIT License. See `LICENSE` file for details.
8 |
9 | Installation
10 | ------------
11 | ### Bower ###
12 | The easy way.
13 |
14 | 1. `bower install angular-dynforms` (add `--save` if you want to add the dependency to your own
15 | project - HIGHLY RECOMMENDED)
16 |
17 | ### Git ###
18 | The old way.
19 |
20 | 1. Clone the project from either [GitHub][] or [BitBucket][] - whichever you prefer.
21 | 2. Copy `dynamic-forms.js` into your project wherever your other assets reside.
22 |
23 | #### Name Change ####
24 | When registering this project with bower, I discovered that there's another project called
25 | [angular-dynamic-forms][wbreza] already registered there. The project was created at the beginning
26 | of October 2014, long after this one, and I haven't yet worked out if there are any similarities in
27 | the implementation, but as I've been thinking of shortening the name of this project for a while
28 | anyway, I went ahead and registered it in bower with the shorter name. I'll be changing the repo
29 | name on GitHub and BitBucket, too, but not for several months, to give existing users time to
30 | notice the addition of full bower support. The repo will be renamed to match the name registered
31 | in bower, and the bower name will not change. It is strongly recommended to use the bower method
32 | so you can get the latest version of this project at any given time, regardless of whether I've
33 | gotten around to renaming the repo.
34 |
35 | Use
36 | ---
37 | As with any other [AngularJS][] module:
38 |
39 | * include the script into your page anywhere after [AngularJS][] itself, using whichever mechanism
40 | you use for including scripts in your project:
41 |
42 | ```html
43 |
44 | ```
45 |
46 | ```javascript
47 | require('angular-dynforms');
48 | ```
49 |
50 | * _**INTERNET EXPLORER**_: This project (as with most of Angular itself) WILL NOT work
51 | properly with IE 6 or 7. Some of the functionality can be coerced into working, but much of it
52 | will simply be broken. `radio` fields, for example, will have every member selected. This may
53 | be fixed in a future version, but as it's 2014, IE 6 and 7 are very low priorities, especially
54 | with XP reaching end of life. IE 8 will work, with a bit of extra setup (you can try this for
55 | IE 6 and 7 as well, but again, they probably won't work):
56 |
57 | ```html
58 |
80 | ```
81 |
82 | * inject `dynform` as a dependency of your project.
83 |
84 | ```javascript
85 | appModule = angular.module('app', ['dynform']);
86 | ```
87 |
88 | * create a [dynamic-form](#the-directive) element anywhere in your page.
89 |
90 | ```html
91 |
94 |
95 | ```
96 |
97 | * populate your [template](#the-template) with a JSON array describing the form you want to create.
98 |
99 | ```javascript
100 | $scope.formData = {}; // JavaScript needs an object to put our form's models into.
101 |
102 | $scope.formTemplate = [
103 | {
104 | "type": "text",
105 | "label": "First Name",
106 | "model": "name.first"
107 | },
108 | {
109 | "type": "text",
110 | "label": "Last Name",
111 | "model": "name.last"
112 | },
113 | {
114 | "type": "email",
115 | "label": "Email Address",
116 | "model": "email"
117 | },
118 | {
119 | "type": "submit",
120 | "model": "submit"
121 | },
122 | ];
123 |
124 | $scope.processForm = function () {
125 | /* Handle the form submission... */
126 | };
127 | ```
128 |
129 | And that's about it! Check out the demo for a more robust example, or keep reading to learn about
130 | all of the things you can do with this module.
131 |
132 | The TL;DR Version
133 | -----------------
134 | ### The Directive ###
135 | You invoke the `dynamic-form` directive using an element (``) - other
136 | options (such as class, attribute, and comment) are unsupported (for now). The directive requires
137 | two attributes: an [`ng-model`][], and either a `template` or a `template-url`. The [`ng-model`][]
138 | will be used to generate valid [`ng-model`][] attributes for the various input controls in the
139 | template. In accordance with how [AngularJS][] handles this attribute elsewhere, your entire form's
140 | data will be available in keys of whichever model you specify here (though nested forms are an
141 | exception, unless you specify a key in the outer form's model as the [`ng-model`][] of the inner
142 | form). **You _must_ initialize this parent model to an object, or your app will break.**
143 |
144 | If you specify a `template-url`, the `dynamic-form` directive will retrieve the form template via
145 | [`$http`][] and build out your form based on the response. Currently, failure is silently ignored.
146 | This may change in a later release.
147 |
148 | You may not want to rely on the directive to retrieve your form directly - perhaps you want to do
149 | some processing on the server response before passing it to the directive for building, or maybe
150 | you need to specify a more complex [`$http`][] request with advanced authentication. Or perhaps you
151 | just want to proactively handle failure to retrieve the template. Enter the `template` attribute.
152 | When the directive sees `template`, it ignores any `template-url` and instead uses the array
153 | identified by the `template` attribute. (See [below](#the-template) for more details on this value.)
154 | At some point in the future you will also be able to dynamically update this array, and the changes
155 | will automatically be reflected in the DOM. This is currently unsupported, however, and for technical
156 | reasons, will likely not be supported at all for `templateUrl` arrays.
157 |
158 | Any other attributes you specify on the `dynamic-form` element are copied across to the `form` or
159 | [`ng-form`][] element that the directive builds to replace itself with. Similarly, any pre-existing
160 | contents are copied across as well, to the top of the resulting form, with the
161 | dynamically-specified controls below them. This allows you to nest `dynamic-form`s inside each
162 | other in the same way as [`ng-form`][] (which is one reason this directive implements this
163 | pseudo-transclusion).
164 |
165 | The `dynamic-form` directive makes every attempt to set up the forms it generates to be valid HTML
166 | forms, complete with the ability to have their data submitted to the server by the browser's native
167 | form submission mechanism and still have the data in the same structure that it takes on in your
168 | [AngularJS][] models. This makes it easy to implement a fallback mode in case there is a problem
169 | with using the standard [Angular][AngularJS] methods to handle your form inputs. You will, of
170 | course, need to provide your own `action` and `method` attributes for this to work completely.
171 |
172 | ### The Template ###
173 | Regardless of whether it arrives via `template` or `template-url`, the form template is a
174 | fairly-straightforward JavaScript array/object. Each index/key of the template value (referred to
175 | elsewhere in this README as an ID) serves as the `name` and [`ng-model`][] (where applicable) of the
176 | control described in the corresponding value. Each of the values, then, is an object describing a
177 | form input control. A `type` key identifies what kind of control to build, which in turn determines
178 | what [other keys](#common-options) are expected. Any `type` that isn't supported builds a ``
179 | containing the value of the `label` key, if one exists, as its content, and any other keys as
180 | attributes.
181 |
182 | ### Supported Control Types ###
183 | Following is a list of all currently-supported `type`s, and then a more detailed specification of
184 | each. Links to Angular documentation in the specifications below indicate that values will be
185 | added to the Angular-defined attributes mentioned, and that Angular provides the actual
186 | functionality described there. Note that not all of these `type`s are properly supported in all
187 | browsers, yet; there are a number of references around the web for [which browsers support
188 | what][formsupport].
189 |
190 | #### Common Options ####
191 | * `attributes`: key-value pairs for arbitrary attributes not otherwise supported here; it is strongly
192 | recommended that you use this option *only* if the attribute you need isn't already supported, as
193 | any attributes specified here bypass any enhancements this module provides.
194 | * `class`: see [`ng-class`][]
195 | * `callback`: see [`ng-change`][] (or [`ng-click`][] for button-like types)
196 | * `disabled`: see [`ng-disabled`][]
197 | * `label`: wraps the control in a `