javascript - how to update ng-model of textarea after manual insert of some text into it -
i have code takes input input area , inserts text @ caret position inside text area, insert part working accurately ng-model of text area fails update same. here code
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) { 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(); } }); } } }])
<!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 src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></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> <p>add text , change caret position , insert test using input area above</p> <textarea my-text="" ng-model="textarea"> </textarea> <p>{{textarea}}</p> </body> </html>
the quickest fix code can think of added below. basically, require ng-model controller directive, , inform when value has changed.
a little off-topic, having mytext directive controlled via global scope (in form of $rootscope.$on) smells bad me.
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 { require: '^ngmodel', // request our containing ng-model controller link: function(scope, element, attrs, ngmodelctrl) { // di $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(); } // inform ng-model value has changed ngmodelctrl.$setviewvalue(domelement.value); }); } } }])
<!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 src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.5/angular.min.js"></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> <p>add text , change caret position , insert test using input area above</p> <textarea my-text="" ng-model="textarea"> </textarea> <p>{{textarea}}</p> </body> </html>
Comments
Post a Comment