Commit | Line | Data |
---|---|---|
66aa0f5e TO |
1 | # org.civicrm.afform |
2 | ||
3 | ![Screenshot](/images/screenshot.png) | |
4 | ||
83291832 TO |
5 | The Affable Administrative Angular Form Framework (`afform`) is a system for administering AngularJS-based forms |
6 | in CiviCRM which: | |
7 | ||
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. | |
66aa0f5e TO |
10 | |
11 | The extension is licensed under [AGPL-3.0](LICENSE.txt). | |
12 | ||
13 | ## Requirements | |
14 | ||
15 | * PHP v5.4+ | |
83291832 | 16 | * CiviCRM v5.3+ |
66aa0f5e TO |
17 | |
18 | ## Installation (Web UI) | |
19 | ||
20 | This extension has not yet been published for installation via the web UI. | |
21 | ||
22 | ## Installation (CLI, Zip) | |
23 | ||
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). | |
26 | ||
27 | ```bash | |
28 | cd <extension-dir> | |
29 | cv dl org.civicrm.afform@https://github.com/FIXME/org.civicrm.afform/archive/master.zip | |
30 | ``` | |
31 | ||
32 | ## Installation (CLI, Git) | |
33 | ||
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). | |
36 | ||
37 | ```bash | |
38 | git clone https://github.com/FIXME/org.civicrm.afform.git | |
39 | cv en afform | |
40 | ``` | |
41 | ||
76a5831d | 42 | ## Development: Quick Start |
66aa0f5e | 43 | |
1e03a3c1 TO |
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`: | |
47 | ||
48 | ``` | |
49 | $ cd /path/to/my/own/extension | |
50 | $ mkdir -p afform/foobar | |
76a5831d TO |
51 | $ echo '{"server_route": "civicrm/pretty-page"}' > afform/foobar/meta.json |
52 | $ echo '<div>Hello {{routeParams.name}}</div>' > afform/foobar/layout.html | |
1e03a3c1 | 53 | $ cv flush |
76a5831d TO |
54 | ``` |
55 | ||
56 | A few things to note: | |
57 | ||
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. | |
63 | ||
64 | Now that we've created a form, we'll want to determine its URL: | |
65 | ||
66 | ``` | |
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" | |
1e03a3c1 TO |
71 | ``` |
72 | ||
73 | You can open the given URL in a web-browser. | |
74 | ||
76a5831d | 75 | ## Development: Form CRUD API |
1e03a3c1 | 76 | |
76a5831d TO |
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. | |
1e03a3c1 TO |
79 | |
80 | ``` | |
81 | $ cv api afform.getsingle name=foobar | |
82 | { | |
83 | "name": "foobar", | |
84 | "requires": [ | |
85 | "afform", | |
86 | "crmUi", | |
87 | "crmUtil" | |
88 | ], | |
89 | "title": "", | |
90 | "description": "", | |
91 | "layout": { | |
92 | "#tag": "div", | |
93 | "#children": [ | |
76a5831d | 94 | "Hello {{routeParams.name}}" |
1e03a3c1 TO |
95 | ] |
96 | }, | |
97 | "id": "foobar" | |
98 | } | |
99 | $ cv api afform.create name=foobar title="The Foo Bar Screen" | |
100 | { | |
101 | "is_error": 0, | |
102 | "version": 3, | |
103 | "count": 2, | |
104 | "values": { | |
105 | "name": "foobar", | |
106 | "title": "The Foo Bar Screen" | |
107 | } | |
108 | } | |
109 | ``` | |
110 | ||
76a5831d TO |
111 | ## Development: Scope variables and functions |
112 | ||
113 | In AngularJS, every component has its own *scope* -- which defines a list of variables you can access. | |
114 | ||
115 | By default, `afform` provides a few variables in the scope of every form: | |
116 | ||
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')}}`. | |
1e03a3c1 | 120 | |
76a5831d | 121 | ## Development: Every form is an AngularJS directive |
66aa0f5e | 122 | |
76a5831d TO |
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. | |
bb56ac78 | 125 | |
76a5831d TO |
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 | |
128 | two small steps: | |
bb56ac78 | 129 | |
76a5831d TO |
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>`. | |
133 | ||
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: | |
136 | ||
137 | ```html | |
138 | <div afform-foobar="{phaseOfMoon: 'waxing'}"></div> | |
139 | ``` | |
140 | ||
141 | Now, in `afform/foobar/layout.html`, you can use the `phaseOfMoon`: | |
142 | ||
143 | ```html | |
144 | Hello, {{routeParams.name}}. The moon is currently {{options.phaseOfMoon}}. | |
145 | ``` | |
146 | ||
147 | ||
148 | ```html | |
149 | Hello, {{routeParams.name ? routeParams.name : 'anonymous'}}. The moon is currently {{options.phaseOfMoon ? options.phaseOfMoon : 'on hiatus'}}. | |
150 | ``` | |
bb56ac78 | 151 | |
66aa0f5e TO |
152 | ## Known Issues |
153 | ||
83291832 TO |
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. | |
76a5831d | 158 | * We generally need to provide more services for managing/accessing data (e.g. `crm-api3`). |