3 ![Screenshot](/images/screenshot.png)
5 The Affable Administrative Angular Form Framework (`afform`) is a system for administering AngularJS-based forms
8 1. Allows developers to declaratively define a canonical, baseline form.
9 2. Allows administrators (or administrative tools) to use the API to revise the forms.
11 The extension is licensed under [AGPL-3.0](LICENSE.txt).
18 ## Installation (Web UI)
20 This extension has not yet been published for installation via the web UI.
22 ## Installation (CLI, Zip)
24 Sysadmins and developers may download the `.zip` file for this extension and
25 install it with the command-line tool [cv](https://github.com/civicrm/cv).
29 cv dl org.civicrm.afform@https://github.com/FIXME/org.civicrm.afform/archive/master.zip
32 ## Installation (CLI, Git)
34 Sysadmins and developers may clone the [Git](https://en.wikipedia.org/wiki/Git) repo for this extension and
35 install it with the command-line tool [cv](https://github.com/civicrm/cv).
38 git clone https://github.com/FIXME/org.civicrm.afform.git
42 ## Development: Quick Start
44 As an upstream publisher of a form, you can define the default, canonical
45 substance of the form by creating a folder named `afform/<MY-FORM>`. In
46 this example, we create a form named `foobar`:
49 $ cd /path/to/my/own/extension
50 $ mkdir -p afform/foobar
51 $ echo '{"server_route": "civicrm/pretty-page"}' > afform/foobar/meta.json
52 $ echo '<div>Hello {{routeParams.name}}</div>' > afform/foobar/layout.html
58 * The file `layout.html` is an AngularJS HTML document. It has access to all the general templating features, such as variable substition
59 (`{{routeParams.name}}`) and the standard library of directives (`ng-if`, `ng-style`, `ng-repeat`, etc).
60 * After creating a new form or file, we should flush the cache.
61 * If you're going to actively edit/revise the content of the file, then you should navigate
62 to **Administer > System Settings > Debugging** and disable asset caching.
64 Now that we've created a form, we'll want to determine its URL:
67 $ cv url civicrm/pretty-page
68 "http://dmaster.localhost/civicrm/pretty-page"
69 $ cv url civicrm/pretty-page/#/?name=world
70 "http://dmaster.localhost/civicrm/pretty-page/#/?name=world"
73 You can open the given URL in a web-browser.
75 ## Development: Form CRUD API
77 Now that we've defined a baseline form, it's possible for administrators and
78 GUI applications to inspect and revise this form using the API.
81 $ cv api afform.getsingle name=foobar
94 "Hello {{routeParams.name}}"
99 $ cv api afform.create name=foobar title="The Foo Bar Screen"
106 "title": "The Foo Bar Screen"
111 ## Development: Scope variables and functions
113 In AngularJS, every component has its own *scope* -- which defines a list of variables you can access.
115 By default, `afform` provides a few variables in the scope of every form:
117 * `routeParams`: This is a reference to the [$routeParams](https://docs.angularjs.org/api/ngRoute/service/$routeParams)
118 service. In the example, we used `routeParams` to get a reference to a `name` from the URL.
119 * `ts`: This is a utility function which translates strings, as in `{{ts('Hello world')}}`.
121 ## Development: Every form is an AngularJS directive
123 In the quick-start example, we registered a new route (`"server_route": "civicrm/pretty-page"`) -- this created a
124 standalone page with the sole purpose of displaying the `foobar` form.
126 However, there's no obligation to use the `foobar` form in a standalone fashion. Think of `foobar` as a *re-usable
127 sub-form* or as a *directive*. If you've created an AngluarJS application, then you can embed `foobar` with
130 1. In your application, declare a dependency on module `afformFoobar`. This is usually done in `ang/MYMODULE.ang.php`
131 and/or `ang/MYMODULE.js`.
132 2. In your HTML template, use the directive `<div afform-foobar=""></div>`.
134 This technique is particularly useful if you want to provide extra data for the form author to use. For example, your
135 application might pass in the current phase of the moon:
138 <div afform-foobar="{phaseOfMoon: 'waxing'}"></div>
141 Now, in `afform/foobar/layout.html`, you can use the `phaseOfMoon`:
144 Hello, {{routeParams.name}}. The moon is currently {{options.phaseOfMoon}}.
149 Hello, {{routeParams.name ? routeParams.name : 'anonymous'}}. The moon is currently {{options.phaseOfMoon ? options.phaseOfMoon : 'on hiatus'}}.
154 * The code is currently written as a proof-of-concept. There are several `FIXME`/`TODO` declarations in the code
155 for checking pre-conditions, reporting errors, handling edge-cases, etc.
156 * Although afforms are can be used in AngularJS, they don't fully support tooling like `cv ang:html:list`
157 and `hook_civicrm_alterAngular`. We'll need a core patch to allow that.
158 * We generally need to provide more services for managing/accessing data (e.g. `crm-api3`).