Update planning-v0.3.md
[civicrm-core.git] / ext / afform / docs / writing.md
1 # Writing Forms: Afform as basic AngularJS templates
2
3 In AngularJS, the primary language for composing a screen is HTML. You can do interesting things in Angular
4 HTML, such as displaying variables and applying directives.
5
6 One key concept is *scope* -- the *scope* determines the list of variables which you can access. By default, `afform`
7 creates a scope with these variables:
8
9 * `routeParams`: This is a reference to the [$routeParams](https://docs.angularjs.org/api/ngRoute/service/$routeParams)
10 service. In the example, we used `routeParams` to get a reference to a `name` from the URL.
11 * `meta`: The stored meta data (`*.aff.json`) for this form.
12 * `ts`: This is a utility function which translates strings, as in `{{ts('Hello world')}}`.
13
14 Additionally, AngularJS allows *directives* -- these are extensions to HTML (custom tags and attributes) which create behavior. For example:
15
16 * `ng-if` will conditionally create or destroy elements in the page.
17 * `ng-repeat` will loop through data.
18 * `ng-style` and `ng-class` will conditionally apply styling.
19
20 A full explanation of these features is out-of-scope for this document, but the key point is that you can use standard
21 AngularJS markup.
22
23 ## Example: Contact record
24
25 Let's say we want `civicrm/hello-world` to become a basic "View Contact" page. A user
26 would request a URL like:
27
28 ```
29 http://dmaster.localhost/civicrm/hello-world/#/?cid=123
30 ```
31
32 How do we use the `cid` to get information about the contact? Update `helloWorld.aff.html` to fetch data with
33 `Contact.get` API and call the [afform-api3](https://github.com/totten/afform/blob/master/ang/afformCore/Api3Ctrl.md) utility:
34
35 ```html
36 <div ng-if="!routeParams.cid">
37 {{ts('Please provide the "cid"')}}
38 </div>
39 <div ng-if="routeParams.cid"
40 afform-api3="['Contact', 'get', {id: routeParams.cid}]"
41 afform-api3-ctrl="apiData">
42
43 <div ng-repeat="contact in apiData.result.values">
44 <h1 crm-page-title="">{{contact.display_name}}</h1>
45
46 <h3>Key Contact Fields</h3>
47
48 <div><strong>Contact ID</strong>: {{contact.contact_id}}</div>
49 <div><strong>Contact Type</strong>: {{contact.contact_type}}</div>
50 <div><strong>Display Name</strong>: {{contact.display_name}}</div>
51 <div><strong>First Name</strong>: {{contact.first_name}}</div>
52 <div><strong>Last Name</strong>: {{contact.last_name}}</div>
53
54 <h3>Full Contact record</h3>
55
56 <pre>{{contact|json}}</pre>
57 </div>
58 </div>
59 ```
60
61 This example is useful pedagogically and may be useful in a crunch -- but
62 for typical user-managed forms, it would be better to use more high-level
63 directives. You can create such directives by [embedding forms](embed.md)
64 or creating [conventional AngularJS directives](angular.md).