├── .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 | [![Join the chat at https://gitter.im/danhunsaker/angular-dynamic-forms](https://badges.gitter.im/danhunsaker/angular-dynamic-forms.svg)](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 `