2

I want to add a field on Case type setting (civicrm/a/#/caseType/1 which is build in angular js) either just below the description field or as a tab besides case role tab. What is the easiest way to do this?

Civi version - 5.14.0

  • Do you also need it to be stored in the xml definition and/or available from api CaseType.get? I've looked into that part before and I didn't see a way to do it without hacking core. – Demerit Jun 29 at 13:28
  • Yes i need to save that into different table probably as a custom field for case type. – Pradeep Nayak Jun 29 at 13:29
  • As part of this lab.civicrm.org/dev/core/issues/1046 I was thinking about proposing a hook that could be a first step towards custom fields for case types, but I'm still in planning stages. – Demerit Jun 29 at 13:32
1

If you're ok with it not being tightly integrated (i.e. automatically available in the xml or to the api), then you can do something like below, which adds a field labelled "Boo" to the case type edit screen.

Thanks for asking this question. It's probably helped me more than you, since it's helped clarify for me how this all works. And it occurs to me that customizing an existing form is probably a much more likely task for developers than writing your own angular form from scratch, which is what all the tutorials show.

function myextension_civicrm_alterAngular(\Civi\Angular\Manager $angular) {
  $changeSet = \Civi\Angular\ChangeSet::create('add_casetype_custom_field')
    ->alterHtml('~/crmCaseType/caseTypeDetails.html',
      function (phpQueryObject $doc) {
        $doc->find('div.crm-group')->append('
          <fieldset class="crm-collapsible">
            <legend class="collapsible-title">{{ ts(\'My Custom Fields\') }}</legend>
            <div ng-controller="CustomFieldCtrl">
              <div crm-ui-field="{name: \'mycustomfield\', title: ts(\'Boo\')}">
                <input crm-ui-id="mycustomfield" class="crm-form-text" name="mycustomfield" ng-model="mymodel.cusfield">
              </div>
            </div>
          </fieldset>
        ');
      });
  $angular->add($changeSet);

  CRM_Core_Resources::singleton()->addScriptFile('my.extension.name', 'js/angCustomField.js');
}

Reference: https://docs.civicrm.org/dev/en/latest/framework/angular/changeset/

And here is the contents of js/angCustomField.js:

(function(angular, $) {
  var crmCaseType = angular.module('crmCaseType');
  crmCaseType.controller('CustomFieldCtrl', function($scope) {
    // Need to replace this with an ajax call right here to look up the value from the db.
    $scope.mymodel = { cusfield: 'value looked up from db' };

    // just show that this is executing and we have the right id
    console.log($scope.caseType.id);

    // alias the real save() function so that we can do our stuff too
    var proxiedSave = $scope.$parent.$parent.save;
    $scope.$parent.$parent.save = function() {
      console.log($scope.caseType.id);
      console.log($scope.mymodel.cusfield);

      //
      // Do ajax api or whatever here to save the value to db
      //
      // IMPORTANT: Always validate the input server-side before using it even if you have javascript validation client-side since that can be easily bypassed. This isn't specific to angular it just seems to be ignored in all the angular tutorials. Even a plain html form with e.g. a select list can still submit values not in the select list - always need to validate server-side.

      // Now call the original save
      return proxiedSave.apply(this);
    }
  });
})(angular, CRM.$);

Some notes:

  • Note we're adding our own nested child controller in the line that has ng-controller="CustomFieldCtrl". This matches up to the controller in our js file.
  • The ng-model="mymodel.cusfield" value HAS TO HAVE A DOT IN IT. It just doesn't work if it doesn't. This matches up to the $scope.mymodel = ... line in our js file.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.