Issue
I am implementing a angularJS text inserter into a text area which inserts the specified text at the position of the cursor in the text area. I found this example online after a little bit of googling.
The main body of the directive is here
app.directive('myText', ['$rootScope', function($rootScope) {
return {
link: function(scope, element, attrs) {
$rootScope.$on('add', function(e, val) {
var domElement = element[0];
if (document.selection) {
domElement.focus();
var sel = document.selection.createRange();
sel.text = val;
domElement.focus();
} else if (domElement.selectionStart || domElement.selectionStart === 0) {
var startPos = domElement.selectionStart;
var endPos = domElement.selectionEnd;
var scrollTop = domElement.scrollTop;
domElement.value = domElement.value.substring(0, startPos) + val + domElement.value.substring(endPos, domElement.value.length);
domElement.focus();
domElement.selectionStart = startPos + val.length;
domElement.selectionEnd = startPos + val.length;
domElement.scrollTop = scrollTop;
} else {
domElement.value += val;
domElement.focus();
}
});
}
}
}])
A working example can be found here http://plnkr.co/edit/f496Mh?p=preview
This is working absolutely fine on all browsers apart from Microsoft Edge where it disregards the position of the cursor and sets the selectionStart and End property back to 0.
I've investigated the issue and found that if I change the div "add" to a button it will work as expected in Edge but would prefer to be able to use a div if at all posible.
Have I missed something here or is this a bug with the browser?
Solution
Edge needs the focus()
set before selectionStart
or selectionEnd
are used.
The other browsers appear to assume focus from the context of the element being used. I came across this question while using JS in the browser, haven't used Angular before, but the problem seems to be common in both.
The modified code below works in Plunker.
app.directive('myText', ['$rootScope', function($rootScope) {
return {
link: function(scope, element, attrs) {
$rootScope.$on('add', function(e, val) {
var domElement = element[0];
if (document.selection) {
domElement.focus();
var sel = document.selection.createRange();
sel.text = val;
domElement.focus();
} else if (domElement.selectionStart || domElement.selectionStart === 0) {
domElement.focus();
var startPos = domElement.selectionStart;
var endPos = domElement.selectionEnd;
var scrollTop = domElement.scrollTop;
domElement.value = domElement.value.substring(0, startPos) + val + domElement.value.substring(endPos, domElement.value.length);
domElement.selectionStart = startPos + val.length;
domElement.selectionEnd = startPos + val.length;
domElement.scrollTop = scrollTop;
} else {
domElement.value += val;
domElement.focus();
}
});
}
}
}])
If anyone is interested in the non-Angular version, the following is what I used. The code is called by a button where textareaElement can have selected text:
var el= document.getElementById('textareaElement');
var selectionStart = el.selectionStart;
var selectionEnd = el.selectionEnd ;
//selectionStart and selectionEnd are always 0 in Edge
var el= document.getElementById('textareaElement');
el.focus();
var selectionStart = el.selectionStart;
var selectionEnd = el.selectionEnd;
//selectionStart and selectionEnd are where textareaElement's selected text start and end in Edge (and other browsers)
Answered By - Nick
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.