(* FIXME *)
+## Usage (Developers): Include a customizable subform in your own page
+
+Suppose you've created an AngularJS UI based on [the developer
+documentation](https://docs.civicrm.org/dev/en/latest/framework/angular/quickstart/). You'd like to use the
+customizable `foobar` form as part of your UI. Fortunately, `foobar` is available as an AngularJS module named
+`afformFoobar`. You can use it with two steps:
+
+1. In your module metadata (`ang/MYMODULE.ang.php`), update the `requires` to include `afformFoobar`.
+2. In your HTML template, use the directive `<div afform-foobar="..."></div>`.
+
## Known Issues
(* FIXME *)
*/
function afform_civicrm_angularModules(&$angularModules) {
_afform_civix_civicrm_angularModules($angularModules);
+
+ $scanner = new CRM_Afform_AfformScanner();
+ $names = array_keys($scanner->findFilePaths());
+ foreach ($names as $name) {
+ $meta = $scanner->getMeta($name);
+ $angularModules[_afform_angular_module_name($name)] = [
+ 'ext' => E::LONG_NAME,
+ 'js' => ['assetBuilder://afform.js?name=' . urlencode($name)],
+ 'requires' => $meta['requires'],
+ 'basePages' => [],
+ ];
+
+ // FIXME: The HTML layout template is embedded in the JS asset.
+ // This works at runtime for basic usage, but it bypasses
+ // the hook_alterAngular infrastructure, and I'm not sure translation works.
+ // We should update core so that 'partials' can be specified more dynamically.
+ }
}
/**
// --- Functions below this ship commented out. Uncomment as required. ---
+/**
+ * Implements hook_civicrm_buildAsset().
+ */
+function afform_civicrm_buildAsset($asset, $params, &$mimeType, &$content) {
+ if ($asset !== 'afform.js') {
+ return;
+ }
+
+ if (empty($params['name'])) {
+ throw new RuntimeException("Missing required parameter: afform.js?name=NAME");
+ }
+
+ $name = $params['name'];
+ $meta = civicrm_api3('Afform', 'getsingle', ['name' => $name]);
+ $scanner = new CRM_Afform_AfformScanner();
+
+ $smarty = CRM_Core_Smarty::singleton();
+ $smarty->assign('afform', [
+ 'camel' => _afform_angular_module_name($name),
+ 'meta' => $meta,
+ 'layout' => file_get_contents($scanner->findFilePath($name, 'layout.html'))
+ ]);
+ $mimeType = 'text/javascript';
+ $content = $smarty->fetch('afform/FormAsDirective.tpl');
+}
+
+/**
+ * @param $name
+ * @return string
+ */
+function _afform_angular_module_name($name) {
+ return 'afform' . strtoupper($name{0}) . substr($name, 1);
+}
+
/**
* Implements hook_civicrm_preProcess().
*
--- /dev/null
+{* This takes an $afform and generates an AngularJS directive.
+
+ @param string $afform.camel The full camel-case name of the AngularJS module being created
+ @param string $afform.meta The full metadata record of the form
+ @param string $afform.layout The template content
+ *}
+{literal}
+(function(angular, $, _) {
+ angular.module('{/literal}{$afform.camel}{literal}', CRM.angRequires('{/literal}{$afform.camel}{literal}'));
+ angular.module('{/literal}{$afform.camel}{literal}').directive('{/literal}{$afform.camel}{literal}', function() {
+ return {
+ restrict: 'AE',
+ template: {/literal}{$afform.layout|json}{literal},
+ scope: {
+ {/literal}{$afform.camel}{literal}: '='
+ },
+ link: function($scope, $el, $attr) {
+ var ts = $scope.ts = CRM.ts('{/literal}{$afform.camel}{literal}');
+ $scope.$watch('{/literal}{$afform.camel}{literal}', function(newValue){
+ $scope.myOptions = newValue;
+ });
+ }
+ };
+ });
+})(angular, CRM.$, CRM._);
+{/literal}
\ No newline at end of file