<!DOCTYPE html>
<html>

  <head>
    <!--External Packages-->
    
    <!-- include libraries(jQuery, bootstrap) -->
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.js"></script> 
    <script src="https://netdna.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.js"></script> 
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
  
    <!-- include summernote css/js-->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.2/summernote.css" rel="stylesheet">
    <script src="https://cdnjs.cloudflare.com/ajax/libs/summernote/0.8.2/summernote.js"></script>
    
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-summernote/0.8.1/angular-summernote.js"></script>
    
        <!--Custom scripts-->
    <script src="script.js"></script>
    <!-- <script src="summernote/templateCtrl.js"></script>-->
    
    <!--Plugins-->
    <!-- <script src="summernote-ext-template.js"></script>-->
    <script src="summernote-ext-dropdown.js"></script>
    

  </head>

  <body ng-app="myApp" ng-controller="MyCtrl">
    <div style="padding: 2em;">
      <h2><span>Summernote sample with plugin</span></h2>
    </div>

    <summernote config="options" ng-model="text"></summernote>
    <p ng-bind="text">
    <script>
/*
    jQuery(document).ready(function(){

        $('#summernote').summernote({
            height: 250,                 // set editor height
            minHeight: null,             // set minimum height of editor
            maxHeight: null,             // set maximum height of editor
            focus: false,                 // set focus to editable area after initializing summernote
            toolbar: [
                ['style', ['style']],
                ['font', ['bold', 'italic', 'underline', 'clear']],
                ['fontname', ['fontname']],
                ['color', ['color']],
                ['para', ['ul', 'ol', 'paragraph']],
                ['height', ['height']],
                ['table', ['table']],
                ['insert', ['template', 'link', 'picture', 'hr']],
                ['view', ['fullscreen', 'codeview']],
                ['help', ['help']]
            ],
            template: {
                path: 'summernote', // path to your template folder
                list: [ // list of your template (without the .html extension)
                    'template1',
                    'template2'
                ]
            }
        });

        $('.inline-editor').summernote({
            airMode: true
        });

    });
    */
</script>
  </body>

</html>
// Code goes here

app = angular.module("myApp", ['summernote']);

app.controller("MyCtrl", function($scope){
  $scope.testFromCtrl = "TestFromCtrl Approved";

$scope.options = {
  height: 250,
  minHeight: null,
  maxHeight: null,
  focus: false,
              toolbar: [
                ['style', ['style']],
                ['font', ['bold', 'italic', 'underline', 'clear']],
                ['fontname', ['fontname']],
                ['color', ['color']],
                ['para', ['ul', 'ol', 'paragraph']],
                ['height', ['height']],
                ['table', ['table']],
                ['insert', ['template','macroList', 'link', 'picture', 'hr']],
                ['view', ['fullscreen', 'codeview']],
                //['help', ['help']],
                //['insert', ['macroList']],
            ],
            template: {
                path: 'summernote', // path to your template folder
                list: [ // list of your template (without the .html extension)
                    'template1',
                    'template2'
                ],
            },
            macroList: 
            {
                blockChar : '%',
                items: ['blockChainId','attachement','address'],
                items1: [{value:'blockChainId', content:'blockChainId'},
                       {value:'attachement', content:'attachement'},
                       {value:'address', content:'address'}],
            },
           hint: {
              words: ['blockChainId','attachement','address'],
              //match: /^[%]([^]*)$/,
              match: /\B%(\w*)$/,
              blockChar : '%',
              search: function (keyword, callback) {
                var bc = this.blockChar;
                /*if (this.blockChar == keyword)
                //show all
                  callback($.grep(this.words, function (item) {
                    return true;
                  }));
                else */
                callback($.grep(this.words, function (item) {
                  if (typeof item === 'string')
                      return item.indexOf(keyword) === 0;
                }));
                
              },
              content: function(item)
              {
                return this.blockChar + item + this.blockChar;
              }
           },
};
  
  
  
});

/*


app.directive("mydirective", ['$parse', function($parse){
  return {
    template: "<h4>My Directive: </h4><h3>{{vdata}}/ {{vobj.value}}</h3",
    scope:{
      vdata: "@",
      vobj: "="
    }
  }
  
}]);


  app.directive('dynamicElement', ['$compile', function ($compile) {
      return { 
        restrict: 'E', 
        scope: {
            message: "="
        },
        replace: true,
        link: function(scope, element, attrs) {
            var template = $compile(scope.message)(scope);
            element.replaceWith(template);               
        },
        controller: ['$scope', function($scope) {
           $scope.clickMe = function(){
                alert("hi");
           };
        }]
      }
  }]);
*/
/* Styles go here */


(function (factory) {
  /* global define */
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['jquery'], factory);
  } else if (typeof module === 'object' && module.exports) {
    // Node/CommonJS
    module.exports = factory(require('jquery'));
  } else {
    // Browser globals
    factory(window.jQuery);
  }
}(function ($) {
  $.extend($.summernote.options, {
    template: {
      list: []
    }
  });

  // Extends plugins for adding templates.
  //  - plugin is external module for customizing.
  $.extend($.summernote.plugins, {
    /**
     * @param {Object} context - context object has status of editor.
     */
    'template': function (context) {
      // ui has renders to build ui elements.
      //  - you can create a button with `ui.button`
      var ui      = $.summernote.ui;
      var options = context.options.template;
      var defaultOptions = {
        label: "Template",
        tooltip: "Insert Template"
      };

      // Assign default values if not supplied
      for (var propertyName in defaultOptions) {
        if (options.hasOwnProperty(propertyName) === false) {
          options[propertyName] = defaultOptions[propertyName];
        }
      }

      // add hello button
      context.memo('button.template', function () {
        // create button
        var button = ui.buttonGroup([
          ui.button({
            className: 'dropdown-toggle',
            contents: '<span class="template"/> ' + options.label + ' <span class="caret"></span>',
            tooltip: options.tooltip,
            data: {
              toggle: 'dropdown'
            }
          }),
          ui.dropdown({
            className: 'dropdown-template',
            items: options.list,
            click: function (event) {
              event.preventDefault();
              
              var $button = $(event.target);
              var value   = $button.data('value');
              var path    = options.path + '/' + value + '.html';

              $.get(path)
                  .done(function (data) {
                    console.log(data);
                    var node = document.createElement('span');
                    var inserted = 
                    "<dynamic-element message='"+data+"'></dynamic-element>";
                    node.innerHTML = data;
                    console.log(angular.module);
                    context.invoke('editor.insertNode', node);
                  }).fail(function () {
                alert('template not found in ' + path);
              });
            }
          })
        ]);

        // create jQuery object from button instance.
        return button.render();
      });
    }
  });
}));

<div ng-controller="TemplateCtrl">
  
{{testFromCtrl}}
My Directive: <mydirective vdata="StringData" vobj="{value: 'Object Value'}"></mydirective>

</div>
<h2>Template 2</h2>
app.controller("TemplateCtrl", function($scope) {
  $scope.testFromCtrl = "TestFromCtrl Approved";

  $scope.vdata = "String";
  $scope.vobj = {
    value: "My object value hehe"
  };
  

});
(function(factory) {
    /* global define */
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['jquery'], factory);
    } else if (typeof module === 'object' && module.exports) {
        // Node/CommonJS
        module.exports = factory(require('jquery'));
    } else {
        // Browser globals
        factory(window.jQuery);
    }
}(function($) {

    /**
     * @class plugin.macro-dropdown
     *
     * Initialize in the toolbar like so:
     *   toolbar: ['insert', ['macroList']]
     *
     * Ultimus Custom Macro Plugin
     */
    $.extend($.summernote.plugins, {
        /**
         * @param {Object} context - context object has status of editor.
         */
        'macroList': function(context) {
            var self = this;

            var options = context.options.macroList;
            var defaultOptions = {
              label: "Macro",
              tooltip: "Insert Macro",
              blockChar : '%',
            };
      
            // Assign default values if not supplied
            for (var propertyName in defaultOptions) {
              if (options.hasOwnProperty(propertyName) === false) {
                options[propertyName] = defaultOptions[propertyName];
              }
            }
            
            // ui has renders to build ui elements.
            //  - you can create a button with `ui.button`
            var ui = $.summernote.ui;

            // add macro toolbar button
            context.memo('button.macroList', function() {
                var list = "";

                var macroButton = ui.buttonGroup([
                    ui.button({
                        className: 'dropdown-toggle',
                        contents: '<span class="template"/> ' + options.label + ' <span class="caret"></span>',
                        tooltip: options.tooltip,
                        data: {
                            toggle: 'dropdown'
                        },
                        click: function () {
                            console.log('macro button click');
                            context.invoke('editor.saveRange');
                        }
                    }),
                    ui.dropdown({
                        className: 'dropdown-style',
                        items: options.items,
                        //contents: list,
                        callback: function($dropdown) {
                          console.log('$dropdown callback');
                          /*
                            $dropdown.find('i').each(function() {
                                $(this).click(function() {
                                    addimg($(this).attr("class"));
                                });
                            });
                            */
                        },
                        click: function (event) {
                          event.preventDefault();
                          
                          var $button = $(event.target);
                          var value   = $button.data('value');
                          var text = options.blockChar + value + options.blockChar;
                          context.invoke('editor.insertText', text);
                          
                          console.log('$dropdown click : ' + options.blockChar + value + options.blockChar);
                        },
                        template: function(item)
                        {
                          var content = (typeof item === 'string') ? item : (item.content || item.value || '');
                          return content;
                        }
                    })
                ]).render();
                return macroButton;
            });

            // This events will be attached when editor is initialized.
            this.events = {
                // This will be called after modules are initialized.
                'summernote.init': function(we, e) {

                    //console.log('summernote initialized', we, e);
                },
                // This will be called when user releases a key on editable.
                'summernote.keyup': function(we, e) {

                    //console.log('summernote keyup', we, e);
                }
            };

            // This methods will be called when editor is destroyed by $('..').summernote('destroy');
            // You should remove elements on `initialize`.
            this.destroy = function() {

            };

            function addimg(value) {
                var img = $('<iframe frameborder="0" class="' + value + '"></iframe>');
                context.invoke('editor.restoreRange');
                context.invoke('editor.focus');
                context.invoke("editor.insertNode", img[0]);
            }
        }
    });

}));