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.