Reputation: 11791
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>
Upvotes: 0
Views: 750
Reputation: 1944
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
Upvotes: 0
Reputation: 8474
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.
Upvotes: 1