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
  
  ```
  <div>
    <input ng-model="schedule.mode" type="radio" name="send" value="recur" id="schedule-send-recur"/>
    <label for="schedule-send-recur">{{ts('Send on a regular basis')}}</label>
  </div>
  
  ```
  
  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](https://civicrm.stackexchange.com/questions/10391) (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](https://docs.angularjs.org/api/ng/service/$compile#-compile-) function, used for template DOM manipulation (is where the template is actually compiled), and the second is the [link](https://docs.angularjs.org/api/ng/service/$compile#-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](https://github.com/civicrm/civicrm-core/blob/master/ang/crmMailing/services.js#L530).
  
  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( '<h1>Text added from compile</h1>' );
  
                  // 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( '<h1>Text added from new link function</h1>' );
  
                  };
              };
  
              // 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](https://gist.github.com/mecachisenros/834e8a38cf4204a5e4d554b471f1f2cf) 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.  
  
  ---
  
  