0

I have the following directive that my application is using. I was under the impression that my application was working fine with AngularJS 1.3 but after a lot of changes including a move to the latest version, the removal of jQuery, and also the use of controller as then now this directive is giving me errors:

app.directive('pagedownAdmin', function ($compile, $timeout) {
    var nextId = 0;
    var converter = Markdown.getSanitizingConverter();
    converter.hooks.chain("preBlockGamut", function (text, rbg) {
        return text.replace(/^ {0,3}""" *\n((?:.*?\n)+?) {0,3}""" *$/gm, function (whole, inner) {
            return "<blockquote>" + rbg(inner) + "</blockquote>\n";
        });
    });

    return {
        require: 'ngModel',
        replace: true,
        scope: {
            modal: '=modal'
        },
        template: '<div class="pagedown-bootstrap-editor"></div>',
        link: function (scope, iElement, attrs, ngModel) {

            var editorUniqueId;

            if (attrs.id == null) {
                editorUniqueId = nextId++;
            } else {
                editorUniqueId = attrs.id;
            }

            var newElement = $compile(
                '<div>' +
                    '<div class="wmd-panel">' +
                        '<div data-ng-hide="modal.wmdPreview == true" id="wmd-button-bar-' + editorUniqueId + '"></div>' +
                            '<textarea data-ng-hide="modal.wmdPreview == true" class="wmd-input" id="wmd-input-' + editorUniqueId + '">' +
                            '</textarea>' +
                        '</div>' +
                    '<div data-ng-show="modal.wmdPreview == true" id="wmd-preview-' + editorUniqueId + '" class="pagedownPreview wmd-panel wmd-preview">test div</div>' +
                '</div>')(scope);

            iElement.html(newElement);

            var help = function () {
                alert("There is no help");
            }

            var editor = new Markdown.Editor(converter, "-" + editorUniqueId, {
                handler: help
            });

            var $wmdInput = iElement.find('#wmd-input-' + editorUniqueId);

            var init = false;

            editor.hooks.chain("onPreviewRefresh", function () {
                var val = $wmdInput.val();
                if (init && val !== ngModel.$modelValue) {
                    $timeout(function () {
                        scope.$apply(function () {
                            ngModel.$setViewValue(val);
                            ngModel.$render();
                        });
                    });
                }
            });

            ngModel.$formatters.push(function (value) {
                init = true;
                $wmdInput.val(value);
                // editor.refreshPreview();
                return value;
            });

            editor.run();
        }
    }
});

Can someone explain to me what the following is doing:

    scope: {
        modal: '=modal'
    },

and also the

    )(scope);

Here is how I am calling this directive:

   <textarea id="modal-data-text"
      class="pagedown-admin wmd-preview-46"
      data-modal="modal"
      data-pagedown-admin
      ng-model="home.modal.data.text"
      ng-required="true"></textarea>

If anyone can see anything that may not work in 2 then I would much appreciate some help. In particular it seems that the following code returns null:

var $wmdInput = iElement.find('#wmd-input-' + editorUniqueId);
Samantha J T Star
  • 30,952
  • 84
  • 245
  • 427
  • what errors are you getting? Also, you say "Here is how I am calling this directive:", but don't show code. – Claies Aug 17 '14 at 18:48
  • $wmdInput is null. For me to be able to report a bit more I would like to know a bit more about what the scope: part of the code is doing. When I pass in data-modal="modal", what exactly is that doing and also (scope) ? – Samantha J T Star Aug 17 '14 at 18:50
  • The `iElement.find('#wmd-input-' + editorUniqueId)` would fail without jQuery, the angular jqLite doesn't support finding element by anything other than tag name. – runTarm Aug 17 '14 at 18:55

1 Answers1

1

You dropped jQuery, so your code now relies on jQLite. Functions of element objects support less functionality when using jqLite. See the full details in the doc: https://docs.angularjs.org/api/ng/function/angular.element

var $wmdInput = iElement.find('#wmd-input-' + editorUniqueId);

Under jqLite, the find function only support searching by tag names, ids will not work. You can use the following tricks from ( AngularJS: How to .find using jqLite? )

// find('#id')
angular.element(document.querySelector('#wmd-input-' + editorUniqueId))

$compile is a service that will compile a template and link it to a scope. https://docs.angularjs.org/api/ng/service/$compile

scope: {
    modal: '=modal'
}

allows you to define a isolated scope for the directive with some bindings to the scope in which the directive is declared. '=' is used for two-way data bindings. Other options are '@ and &' for strings and functions. https://docs.angularjs.org/guide/directive

Community
  • 1
  • 1
apairet
  • 3,162
  • 20
  • 23
  • Can you explain what you mean by tag name? Could I modify my code to do this instead? Sorry I am just not sure what a tag name is. Thanks – Samantha J T Star Aug 17 '14 at 19:04
  • by tag it is meant 'HTML tag'. So you will be able to find 'div' or a 'span'. I have updated the answer – apairet Aug 17 '14 at 19:05