Answers.Body: <p>What you want to do now is <em>decorate</em> the directive ;)</p>
  
  <p>The decorator method allows you to <em>decorate/modify</em> an angular directive/service/factory/controller before its usage/instantiated.</p>
  
  <p>You have two options (that I know of) to manipulate the directives DOM, one is the <a href="https://docs.angularjs.org/api/ng/service/$compile#-compile-" rel="nofollow noreferrer">compile</a> function, used for template DOM manipulation (is where the template is actually compiled), and the second is the <a href="https://docs.angularjs.org/api/ng/service/$compile#-link-" rel="nofollow noreferrer">link</a> function, is where the data/scope is attached to the instantiated element/elements, and usaully used for event listeneres, like $watch</p>
  
  <p>The angular mailing app uses a boilerplate template to declare directives, see the source <a href="https://github.com/civicrm/civicrm-core/blob/master/ang/crmMailing/services.js#L530" rel="nofollow noreferrer">here</a>.</p>
  
  <p>I'll try to explain with inline comments:</p>
  
  <pre><code>angular.module( 'crmMailing' ).config( function( $provide ){
  
          // the callback recieves the directive when the Mailing app bootsraps
          $provide.decorator( 'crmMailingBlockScheduleDirective', function( $delegate ){
  
              // $delegate is an array, we grab and store the directive into the 'directive' variable
              var directive = $delegate[0];
  
              // we hold the original link function 
              var link = directive.link;
  
              // as the link function is already defined in Civi's boilerplate
              // we create the compile function and return a new link function calling apply on the old link function
              directive.compile = function( Element, Attrs ){
  
                  // you can manipulate the directive's template here, like adding your own DOM elements/directives
                  Element.append( '&lt;h1&gt;Text added from compile&lt;/h1&gt;' );
  
                  // return new link function
                  return function( scope, elem, attr ){
  
                      // call apply to get original functionality
                      link.apply( this, arguments );
  
                      // add new functionality here
                      elem.append( '&lt;h1&gt;Text added from new link function&lt;/h1&gt;' );
  
                  };
              };
  
              // always return $delegate
              return $delegate;
          }); 
      });
  </code></pre>
  
  <p>In order for this to work what I do is declare a fake/empty angular module like <code>crmMailSubjectReview = angular.module( 'crmMailSubjectReview', [] );</code>, load it via <code>hook_civicrm_angularModules</code> and then add the <code>crmMailing</code> config block, see <a href="https://gist.github.com/mecachisenros/834e8a38cf4204a5e4d554b471f1f2cf" rel="nofollow noreferrer">here</a> another small example (have a look at the comments to see the template and the end result).</p>
  
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-04-10T13:29:24.197Z
Answers.Text: Thanks for this, Andrei. I have your code example above working. I'm trying to work out when I might use the first example `Element.append()` and when I might try and use the last `Elem.append`. Any ideas? Or should I not worry about it.
Answers.UserDisplayName: michaelmcandrew
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-04-10T22:04:11.010Z
Answers.Text: You usually want to use `compile` (`Element.append()`), specially if you are appending directives, if you try to append a directive in `link` it won't work, as the current directive/element and its children at that point are already instantiated. `link` will render "normal" DOM elements but not angular elements. You could use the `$compile` service injecting it in `link` and then do something like `var myDirective = '<div my-directive></div>'; var compiledEl = $compile(myDirective)($scope); elem.append(compiledEl);` but I think you'll probably run into issues with this approach
Answers.UserDisplayName: Andrei
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-04-10T22:31:38.257Z
Answers.Text: In summary, when using `compile` you are dealing with template DOM elements (angular elements) and when using `link` you are dealing with _jQuery-ish_ elements that can be manipulated based on scope and attributes, if that makes sense
Answers.UserDisplayName: Andrei
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-04-12T10:42:34.087Z
Answers.Text: Thanks - getting there now - will post a link to what i did soon (just polishing slightly) in case that is useful for people...
Answers.UserDisplayName: michaelmcandrew
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-04-13T13:52:34.500Z
Answers.Text: Hey Andrei - in case you're interested, I posted my angular code above.
Answers.UserDisplayName: michaelmcandrew
Answers.ContentLicense: CC BY-SA 3.0
Answers.CreationDate: 2017-04-05T22:21:56.813Z
Answers.LastActivityDate: 2017-04-05T22:21:56.813Z
Answers.UserDisplayName: Andrei
Body: <p>I'm making a first foray into customizing the mailing compose screen.</p>
  
  <p>I want to add a third option to the options in BlockSchedule.html (schedule.mode = regular) which will open up a few more options to allow you to send mailings on a regular basis.</p>
  
  <p>The template code I want to add is along the lines of</p>
  
  <pre><code>&lt;div&gt;
    &lt;input ng-model="schedule.mode" type="radio" name="send" value="recur" id="schedule-send-recur"/&gt;
    &lt;label for="schedule-send-recur"&gt;{{ts('Send on a regular basis')}}&lt;/label&gt;
  &lt;/div&gt;
  </code></pre>
  
  <p>Selecting this will open up a new directive with options for sending on a regular basis. It will also swap the submit mailing button for a schedule mailings button and possibly do other stuff.</p>
  
  <p>But right now, I am stuck on a good way to add this option.</p>
  
  <p><a href="https://civicrm.stackexchange.com/questions/10391">This answer</a> (adapted below) makes me think that something along the lines of the following would work, but what do I do with the directive at this point?! </p>
  
  <pre><code>angular.module('crmMailing').config(function($provide){
     // intercept crmMailingBlockMailing directive, note the 'Directive' suffix
     $provide.decorator('crmMailingBlockScheduleDirective', function($delegate){
          var directive = $delegate[0];
  </code></pre>
  
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-04-05T22:22:16.413Z
Comments.Text: Let me know if there's anything unclear, happy to help!
Comments.UserDisplayName: Andrei
Comments.ContentLicense: CC BY-SA 3.0
Comments.CreationDate: 2017-04-13T13:52:12.323Z
Comments.Text: FYI, I ended up writing [this angular code](https://github.com/3sd/civicrm-recurring-mail/blob/master/ang/civicrm-recurring-mail.js) that works alongside  [this template](https://github.com/3sd/civicrm-recurring-mail/blob/master/ang/crmMailingRecurSchedule.html) and also adds [this extra scheduling option](https://github.com/3sd/civicrm-recurring-mail/blob/master/ang/crmMailingBlockScheduleRecurOption.html)
Comments.UserDisplayName: michaelmcandrew
Tags: <civimail><developer><angular>
Title: Append an option to the BlockSchedule Directive in crmMailing
ThreadText: # Append an option to the BlockSchedule Directive in crmMailing
  
  (Asked by: username_0 on 2017-04-05)
  
  I'm making a first foray into customizing the mailing compose screen.
  I want to add a third option to the options in BlockSchedule.html (schedule.mode = regular) which will open up a few more options to allow you to send mailings on a regular basis.
  The template code I want to add is along the lines of
  
    
    {{ts('Send on a regular basis')}}
  
  
  Selecting this will open up a new directive with options for sending on a regular basis. It will also swap the submit mailing button for a schedule mailings button and possibly do other stuff.
  But right now, I am stuck on a good way to add this option.
  This answer (adapted below) makes me think that something along the lines of the following would work, but what do I do with the directive at this point?! 
  angular.module('crmMailing').config(function($provide){
     // intercept crmMailingBlockMailing directive, note the 'Directive' suffix
     $provide.decorator('crmMailingBlockScheduleDirective', function($delegate){
          var directive = $delegate[0];
  
  **Tags:** civimail, developer, angular
  
  > **Comments:**
  > **username_1**: Let me know if there's anything unclear, happy to help!  
  > **username_0**: FYI, I ended up writing [this angular code](https://github.com/3sd/civicrm-recurring-mail/blob/master/ang/civicrm-recurring-mail.js) that works alongside  [this template](https://github.com/3sd/civicrm-recurring-mail/blob/master/ang/crmMailingRecurSchedule.html) and also adds [this extra scheduling option](https://github.com/3sd/civicrm-recurring-mail/blob/master/ang/crmMailingBlockScheduleRecurOption.html)  
  
  ---
  
  ## 1 answers
  
  ### Answer by username_1 on 2017-04-05. Score: 1 | Accepted answer
  
  What you want to do now is decorate the directive ;)
  The decorator method allows you to decorate/modify an angular directive/service/factory/controller before its usage/instantiated.
  You have two options (that I know of) to manipulate the directives DOM, one is the compile function, used for template DOM manipulation (is where the template is actually compiled), and the second is the link function, is where the data/scope is attached to the instantiated element/elements, and usaully used for event listeneres, like $watch
  The angular mailing app uses a boilerplate template to declare directives, see the source here.
  I'll try to explain with inline comments:
  angular.module( 'crmMailing' ).config( function( $provide ){
  
          // the callback recieves the directive when the Mailing app bootsraps
          $provide.decorator( 'crmMailingBlockScheduleDirective', function( $delegate ){
  
              // $delegate is an array, we grab and store the directive into the 'directive' variable
              var directive = $delegate[0];
  
              // we hold the original link function 
              var link = directive.link;
  
              // as the link function is already defined in Civi's boilerplate
              // we create the compile function and return a new link function calling apply on the old link function
              directive.compile = function( Element, Attrs ){
  
                  // you can manipulate the directive's template here, like adding your own DOM elements/directives
                  Element.append( 'Text added from compile' );
  
                  // return new link function
                  return function( scope, elem, attr ){
  
                      // call apply to get original functionality
                      link.apply( this, arguments );
  
                      // add new functionality here
                      elem.append( 'Text added from new link function' );
  
                  };
              };
  
              // always return $delegate
              return $delegate;
          }); 
      });
  
  In order for this to work what I do is declare a fake/empty angular module like crmMailSubjectReview = angular.module( 'crmMailSubjectReview', [] );, load it via hook_civicrm_angularModules and then add the crmMailing config block, see here another small example (have a look at the comments to see the template and the end result).
  
  > **Comments:**
  > **username_0**: Thanks for this, username_1. I have your code example above working. I'm trying to work out when I might use the first example `Element.append()` and when I might try and use the last `Elem.append`. Any ideas? Or should I not worry about it.  
  > **username_1**: You usually want to use `compile` (`Element.append()`), specially if you are appending directives, if you try to append a directive in `link` it won't work, as the current directive/element and its children at that point are already instantiated. `link` will render "normal" DOM elements but not angular elements. You could use the `$compile` service injecting it in `link` and then do something like `var myDirective = '<div my-directive></div>'; var compiledEl = $compile(myDirective)($scope); elem.append(compiledEl);` but I think you'll probably run into issues with this approach  
  > **username_1**: In summary, when using `compile` you are dealing with template DOM elements (angular elements) and when using `link` you are dealing with _jQuery-ish_ elements that can be manipulated based on scope and attributes, if that makes sense  
  > **username_0**: Thanks - getting there now - will post a link to what i did soon (just polishing slightly) in case that is useful for people...  
  > **username_0**: Hey username_1 - in case you're interested, I posted my angular code above.  
  
  ---
  
  