8

Is it possible to alter the mailing form? I want to set the default value for url_tracking to false. Usually I would write a hook_civicrm_buildForm and set a custom default value but this hook is not being called when loading the mailing form.

  • 1
    The mailing page/form is built with angular, I'm not sure if there's a way to hook into angular, there's a hook_civicrm_AngularModules in the hook reference, that said I guess you'll have to go with JavaScript/jQuery or modify the angular partial at /path/to/civi/civicrm/civicrm/ang/crmMailing/BlockTracking.html adding ng-init="mailing.url_tracking='0'" to the url_tracking input, that will make the checkbox unchecked when the page loads, please note that this is not recommended, you will lose any changes made to those files when upgrading CiviCRM. – Andrei Jan 23 '16 at 12:00
  • I would update the initial value on document ready via JS in my theme. But I can't find a way to check, if the input has already been "touched". I don't want to uncheck the input if the user has set it by himself. – Philipp Michael Jan 25 '16 at 16:08
4

Disclaimer: I'm not an angularjs expert

Again this is a bit of a hack, we are intercepting a built-in CiviCRM angular directive and extending to add behaviour.

Create a custom extensions or use an existing one and implement hook_civicrm_angularModules:

function myextension_civicrm_angularModules(&$angularModules){
        $angularModules['myModule'] = array(
                'ext' => 'myextension',
                'js' => array('js/myModule.js'),
        );
}

In your js file:

// js/myModule.js

(function(angular, $, _){
  // Your module
  angular.module('myModule', []);

  // the hack
  angular.module('crmMailing').config(function($provide){

    // crmMailingBlockTracking directive
    $provide.decorator('crmMailingBlockTrackingDirective', function($delegate){
        var directive = $delegate[0];

        // Original link function
        var link = directive.link;

        // compile function, returns new link function
        directive.compile = function(){
            return function(scope, element, attrs){
                // get old link functionality
                link.apply(this, arguments);

                // new functionality here
                scope.$parent.$watch(attrs.crmMailing, function(){
                    var createdDate = new Date(scope.mailing.created_date).getTime()/1000;
                    var nowDate = new Date().getTime()/1000;

                    if((nowDate - createdDate) < 60){
                        scope.mailing.url_tracking = '0';
                        CRM.alert('Tracking Disabled');
                    }

                }); 
            };
        };

        return $delegate;
    });
  });
})(angular, CRM.$, CRM._);

The angular Mailing app uses a kind of boilerplate service, crmMailingSimpleDirective for constructing directives see here more info

The above snippet will do the same as my other answer without relying on setTimeout().

Hope that helps.

  • That's great, thank you! Folks can also set "Track Opens" to no by default, by using scope.mailing.open_tracking = '0'; instead of or in addition to scope.mailing.url_tracking = '0'; in the js file. – Norris Aug 10 '17 at 0:27
3

I guess this is not the best way to do it and perhaps someone can point you to a better solution. I'll put it as an answer for readability purposes.

Edit

Create a custom extensions or use an exiting and implement hook_civicrm_pageRun, something like:

function myextension_civicrm_pageRun(&$page){
  $pageName = $page->getVar('_name');
  if ($pageName == 'Civi\Angular\Page\Main') {
    CRM_Core_Resources::singleton()->addScriptFile('myextension', 'js/myJsScript.js');
  }
}

Edit: making some assumption this is with what I came up, as I said not the best thing to do but... perhaps someone finds it useful.

// js/myJsScript.js

CRM.$(function($){

  var disableUrlTracking = function(){
    // Access angular $scope
    var mailingElement = document.querySelector('[ng-model="mailing.url_tracking"]');
    var mailingScope = angular.element(mailingElement).scope();

    // Convert the mailing created date into seconds
    var createdDate = new Date(mailingScope.mailing.created_date).getTime()/1000;

    // Current date into seconds
    var nowDate = new Date().getTime()/1000;

    // Compare both dates
    var dif = nowDate - createdDate;

      // if the difference is less 60 seconds, assuming that to creat a mailing takes more than 60 seconds
    if(dif <= 60){
      mailingScope.mailing.url_tracking = '0';
      CRM.alert('URL Tracking disabled', 'URL Tracking');
    }
  }
  // Optional: wait for the page to load completeley, in my case it takes some seconds until it renders the whole mailing page.
  // If you don't have that issue just call the function
  setTimeout(disableUrlTracking, 4000 );

});
  • But if the user enables url_tracking and saves the mailing as draft to finish it later, your code will disable it, when the user opens the page again. – Philipp Michael Jan 26 '16 at 8:03
  • Totally true, I haven't thought about that, my fault, I misunderstood your comment. – Andrei Jan 26 '16 at 8:09
  • Updated the answer, maybe you can find a better way to check if the mailing has been saved as a draft – Andrei Jan 26 '16 at 15:01
  • sorry that I've not accepted your answer. I'm still hoping that there might be an easy way to alter the form. – Philipp Michael Apr 27 '16 at 13:15
  • No worries, I agree there must be a better way to do it, at least it should, perhaps the angular way, but better doesn't necessarily mean easier, have a look at the Api explorer and try a get action on the Mailing entity, the only way I see you could differentiate a saved draft from a new mailing is comparing the created_date with the current date that is being edited, as there's no other property that I can think of that you could check for, for a sent/scheduled mailing you can see that you do have new properties like, is_completed, scheduled_date, scheduled_id, etc – Andrei Apr 28 '16 at 0:01

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.