I have controller MyCtrl
and directive myText
. When a model in MyCtrl
changes, I want to update the textarea
of myText
directive by inserting the text at current position / caret.
I tried to reuse the code from this Inserting a text where cursor is using Javascript/jquery
My Code: http://plnkr.co/edit/WfucIVbls2eekL8kUp7e
Here is my HTML:
<!DOCTYPE html>
<html ng-app="plunker">
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<script>document.write('<base href="' + document.location + '" />');</script>
<link href="style.css" rel="stylesheet" />
<script data-semver="1.2.10" src="http://code.angularjs.org/1.2.10/angular.js" data-require="[email protected]"></script>
<script src="app.js"></script>
</head>
<body>
<div ng-controller="MyCtrl">
<input ng-model="someInput">
<button ng-click="add()">Add</button>
<p ng-repeat="item in items">Created {{ item }}</p>
</div>
<textarea my-text="">
</textarea>
</body>
</html>
Javascript:
var app = angular.module('plunker', []);
app.controller('MyCtrl', function($scope, $rootScope) {
$scope.items = [];
$scope.add = function() {
$scope.items.push($scope.someInput);
$rootScope.$broadcast('add', $scope.someInput);
}
});
app.directive('myText', ['$rootScope', function($rootScope) {
return {
link: function(scope, element, attrs) {
$rootScope.$on('add', function(e, val) {
console.log('on add');
console.log(val);
if (document.selection) {
element.focus();
var sel = document.selection.createRange();
sel.text = val;
element.focus();
} else if (element.selectionStart || element.selectionStart === 0) {
var startPos = element.selectionStart;
var endPos = element.selectionEnd;
var scrollTop = element.scrollTop;
element.value = element.value.substring(0, startPos) + val + element.value.substring(endPos, element.value.length);
element.focus();
element.selectionStart = startPos + val.length;
element.selectionEnd = startPos + val.length;
element.scrollTop = scrollTop;
} else {
element.value += val;
element.focus();
}
});
}
}
}])
It doesn't work now because element
is not the DOM object. Here is the error:
TypeError: Object [object Object] has no method 'focus'
QUESTION: So my question is how to fix this? Or how to get the real DOM object from angular element object?
To add text to a textarea, access the value property on the element and set it to its current value plus the text to be appended, e.g. textarea. value += 'Appended text' . The value property can be used to get and set the content of a textarea element. Here is the HTML for the examples in this article.
First, get the current position of cursor with the help of property named as selectionStart on textarea/inputbox. To insert the text at the given position we will use slice function to break the string into two parts and then we will append both parts to the text(text_to_insert) in front and end of the text.
Overview HTML textarea element control with AngularJS data-binding. The data-binding and validation properties of this element are exactly the same as those of the input element. Known Issues
Textarea elements are being referred to by using the value of the ng-model attribute. <textarea> elements inside an AngularJS application are given certain classes. These classes can be used to style textarea elements according to their state. ng-valid- key One key for each validation.
Here is a working snippet of code to get and set the caret position in HTML textarea and textbox. This code works for IE 6, 7, 8, >=9, Edge, Chrome, Safari, Firefox and Opera. Type the number where you want to set the caret position and click on “Set Position” button. Type the starting character number and end character number.
Attribute ng-model makes reference to text-directive. The current state of textarea elements is held by Angular JS. $touched: It signifies a touched field. $ untouched: It signifies an untouched field. $valid: It signifies valid field content. $invalid: It signifies invalid field content. $dirty: It signifies a modification in field content.
Try:
var domElement = element[0];
DEMO
Short anwser:
element[0]
would give you the actual DOM Element.
Long answer:
angular.element
always provides a jqLite
selector, which is similiar to a result set given by a jQuery selection. It's a set of HTML elements.
The link
function of a method gets called with the following params: scope
, element
, attrs
and ctrl
.
element
is given as a set of the one DOM Element the directive is attached to. So the first item is the actual HTML Element.
I changed your code so that it should(?) work
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With