Home > Developer Guide > Hooks > Form Hooks
hook_civicrm_alterAngular
Summary
This hook alters the definition of some AngularJS HTML partials and allows you to inject AngularJS changesets.
Availability
This hook is available in CiviCRM 4.7.21 and later.
Definition
hook_civicrm_alterAngular(&$angular)
Parameters
- array
$angular
-\Civi\Angular\Manager
Examples
Directly modify the attributes of a form and add a translated attribute
function example_civicrm_alterAngular($angular) {
$angular->add(\Civi\Angular\ChangeSet::create('mychanges')
->alterHtml('~/crmMailing/EditMailingCtrl/2step.html', function(phpQueryObject $doc) {
$doc->find('[ng-form="crmMailingSubform"]')->attr('cat-stevens', 'ts(\'wild world\')');
})
);
}
You can also add a listener and a class that responds to that lisener. In this example the system loops through each field to find the appropriate ones that it needs to modify, and changes the field defintion.
// Listener to modify fields
Civi::dispatcher()->addListener('hook_civicrm_alterAngular',
['CRM_Classname_AfformMetadataInjection', 'preprocess']);
Within your AfformMetadataInjection.php
file:
<?php
use Civi\Core\Event\GenericHookEvent;
use Civi\Core\Service\AutoService;
/**
* Provides ability to modify fields prior to rendering
* @internal
* @service
*/
class CRM_Classname_AfformMetadataInjection extends AutoService {
/**
* @param \Civi\Core\Event\GenericHookEvent $e
* @see CRM_Utils_Hook::alterAngular()
*/
public static function preprocess($event) {
$changeSet = \Civi\Angular\ChangeSet::create('modifySomething')
->alterHtml(';\\.aff\\.html$;', function($doc, $path) {
// You can conditionally restrict it to certain Forms or change them all
if ($path == '~/formname/formname.aff.html') {
// Run through each field and modify the ones that are applicable
foreach (pq('af-field', $doc) as $afField) {
$fieldName = $afField->getAttribute('name');
// Obtain Field Definition
$fieldDefn = self::getFieldDefinition($afField);
if (!$fieldDefn) {
continue;
}
if ($fieldName == 'myfield') {
// Get some data from API calls if you choose to use below
// Change the default value
$fieldDefn['afform_default'] = xyz;
// If you have an option field you can change the values as below
$fieldDefn['options'] = \CRM_Utils_JS::writeObject(array_map(['\CRM_Utils_JS', 'encode'], $optionsReturn));
// Write out the field definition back to the field
pq($afField)->attr('defn', htmlspecialchars(\CRM_Utils_JS::writeObject($fieldDefn), ENT_COMPAT));
}
}
}
});
// Write out the changset
$event->angular->add($changeSet);
}
public static function getFieldDefinition($afField) {
$existingFieldDefn = trim(pq($afField)->attr('defn') ?: '');
if ($existingFieldDefn && $existingFieldDefn[0] != '{') {
// If it's not an object, don't mess with it.
return NULL;
}
return $existingFieldDefn ? \CRM_Utils_JS::getRawProps($existingFieldDefn) : [];
}
}
Hot Tips
After any modification to your angular hooks it is essential to do a system flush to ensure that your changes are seen right away.
FormBuilder caches the changesets and forms so normally your changes don't register until this reset has happened.