0

I am trying to implement a custom directive textareaInput. but I didn't know how implement the custom event for the directive.

The code looks like below.

myApp.directive('textareaInput',function() {
    var textareaInputDir = {};
    textareaInputDir.restrict="E";
    textareaInputDir.replace="true";
    textareaInputDir.templateUrl="../../../views/widget/textarea/textarea-template.html";
    textareaInputDir.scope={};
    textareaInputDir.link=function (scope, jqElement, attrs) {
        scope.elementDefinition={};
        scope.elementDefinition.label=attrs.label;
        scope.elementDefinition.isShow=attrs.isshow;
        scope.elementDefinition.isRequired=attrs.isrequired;
        scope.elementDefinition.isDisabled=(attrs.isdisabled === "true");
        scope.elementDefinition.defaultValue=attrs.defaultvalue;
        scope.keyValue={text:scope.elementDefinition.defaultValue};

    };

    return textareaInputDir;
});

The template html looks like:

<div>
    <textarea ></textarea>
    <label>
        <small></small>
        <span >*</span>
    </label>
</div>

In the view I will use it like below. In below example. I tried to add a ng-change event for my directive. and I want to define the someMethod in the controller testCtrl .but found this event will be attached for the root element of template(it is a div). So it will doesn't make sense .because when the text changed in the textarea , the root element can't know it. So I want all the events defined in the directive like ng-change, ng-click etc can be attached to the child element textarea of template. Is there any way to make it ? thanks.

<form  ng-controller='testCtrl'>
    <textarea-Input label="Project Description" isShow="true" 
    isRequired="true" isDisabled="false" ng-change="someMethod()" ng-click="someClick()"></textarea-Input>

</form>
Joe.wang
  • 11,537
  • 25
  • 103
  • 180

2 Answers2

1

Although I haven't tried this myself I believe you have a scope problem.

You need to use transclude: true in your directive definition and then use the ng-change="someMethod()" inside your text area template as your textarea-input template could include many elements capable of firing a change event. Is your ng-change attribute capture all of them?

For more info look for this "Creating a Directive that Wraps Other Elements" in this long page of Angular JS docs.

This answer will shed some light about Angular JS directive scope issue.

Community
  • 1
  • 1
Fabio Milheiro
  • 8,100
  • 17
  • 57
  • 96
  • `Is your ng-change attribute capture all of them?` actually the `ng-change` doesn't work at all when I change the content in the textarea. – Joe.wang Jul 10 '14 at 11:41
  • 1
    Okay, it makes sense not to as there's nothing connecting it to your textarea. Try having a look at the 2 links in this answer. – Fabio Milheiro Jul 11 '14 at 08:41
0

First you have to get the onChange passed function by making it a scope variable. You could also decide to change the name of the event like "inputChange" to avoid confusion. Then just get the textarea element and bind the callback to it's change event.

myApp.directive('textareaInput',function() {
    var textareaInputDir = {};
    textareaInputDir.restrict="E";
    textareaInputDir.replace="true";
    textareaInputDir.templateUrl="../../../views/widget/textarea/textarea-template.html";
    textareaInputDir.scope= {
        //isolated scope event, better change name anyway
        ngChange: '&' 
    };
    textareaInputDir.link=function (scope, jqElement, attrs) {
        scope.elementDefinition={};
        scope.elementDefinition.label=attrs.label;
        scope.elementDefinition.isShow=attrs.isshow;
        scope.elementDefinition.isRequired=attrs.isrequired;
        scope.elementDefinition.isDisabled=(attrs.isdisabled === "true");
        scope.elementDefinition.defaultValue=attrs.defaultvalue;
        scope.keyValue={text:scope.elementDefinition.defaultValue};

        //get the textarea element
        var inputElement = jqElement.find('textarea');
        //listen for the change event
        inputElement.bind('change', scope.ngChange);

    };

    return textareaInputDir;
});

This should be enough to see it working

Bolza
  • 1,904
  • 2
  • 17
  • 42