Je dois modifier la position du curseur d'une entrée, où un nombre donné de chiffres est ajouté ( Exemple ).
app.controller('MainCtrl', function($scope, $element, $timeout, $filter) {
//$scope.val = '12';
$scope.$watch('val', function(newValue, oldValue) {
if (!isNaN(newValue)) {
if (newValue.length > 3) {
//Set Caret Position
}
}
});
});
Est-il possible de faire quelque chose comme ceci exemple ?
J'ai besoin par exemple:
Entrée: 1234.
la position du curseur sera donc 2.
Nouveau chiffre: 9
finale: 12934
Merci d'avance.
Je pense que ce genre de choses semble mieux dans les directives. Par exemple:
app.directive('caret', function() {
function setCaretPosition(elem, caretPos) {
if (elem !== null) {
if (elem.createTextRange) {
var range = elem.createTextRange();
range.move('character', caretPos);
range.select();
} else {
if (elem.setSelectionRange) {
elem.focus();
elem.setSelectionRange(caretPos, caretPos);
} else
elem.focus();
}
}
}
return {
scope: {value: '=ngModel'},
link: function(scope, element, attrs) {
var caret = Number(attrs.caret);
scope.$watch('value', function(newValue, oldValue) {
if (newValue && newValue != oldValue && !isNaN(newValue) && newValue.length > (caret + 1)) {
setCaretPosition(element[0], caret);
}
});
}
};
});
Usage:
<input ng-model='val' caret="2" />
J'ai utilisé la fonction setCaretPosition
pour positionner le curseur de plusieurs navigateurs entre this answer.
J'ai aussi eu le même problème.
J'ai pensé résoudre le problème en créant une directive appropriée. Vous pouvez le trouver ici . Profitez-en!
Inclure la directive, la déclarer par l'attribut caret-aware
<script src="https://cdn.rawgit.com/leodido/ng-caret-aware/master/caretaware.min.js"></script>
<script type="text/javascript">
var app = angular.module('myModule', ['leodido.caretAware']);
</script>
...
<div data-ng-app="app">
<input type="text" name="myname" caret-aware="cursor"/>
</div>
Ensuite, dans le champ d'application, vous aurez une variable cursor
contenant la position du curseur dans l'entrée nommée myname
.
Néanmoins, le contrôleur de cette directive expose une API
getPosition
setPosition
Pour d'autres exemples d'utilisation, voir le répertoire example
du référentiel github lié ci-dessus.
Je pense que la meilleure approche à cet égard est de créer une directive réutilisable car nous traitons de la manipulation DOM.
Lien vers la démo: http://plnkr.co/edit/qlGi64VO1AOrNpxoKA68?p=preview
var app = angular.module('angularjs-starter', []);
app.controller('MainCtrl', function($scope, $element, $timeout, $filter) {
$scope.$watch('val', function(newValue, oldValue) {
if (!isNaN(newValue)) {
if (newValue.length > 3) {
// $element.find('input')[0].selectionEnd = 2;
}
}
});
});
app.directive('setCaret', function() {
return {
restrict: 'A',
link: function(scope,element,attrs) {
var changed = false;
element.bind('keypress', function() {
if(element[0].selectionStart > 3 && !changed) {
changed = true;
element[0].selectionEnd = parseInt(attrs.position, 10);
}
})
},
}
})
Vous pouvez voir dans la partie commentée du contrôleur que nous pouvons y accéder en utilisant $ element, mais comme il s'agit de DOM et que les contrôleurs ne sont pas destinés à la manipulation du DOM, nous devons en faire une directive.
I jsfiddled une solution qui marche. Donc, en gros, vous devez créer une directive:
app.directive('keypressdetector', function($compile){
return {
restrict:'AEC',
link: function(scope, element, attrs){
element.bind("keypress", function (event) {
if(event.which === 13) {
var selectionStart = element[0].selectionStart;
var value = element.val();
var valueLength = value.length;
var newValue= '';
if (selectionStart == valueLength){
newValue = value;
} else {
newValue = value.substring(selectionStart, valueLength);
}
var newElement = angular.element('<input type="text" value="' + newValue +'"/>')
angular.element(document.body).append(newElement);
}
});
}
};
});
Votre contrôleur serait inutilisable dans cette situation. Vous pouvez invoquer la directive comme ceci (voir: keypressdetector):
<div ng-app="myapp">
<div ng-controller="LoginController">
<div>Hello {{ user.firstName }}</div>
<input ng-model="user.firstName" keypressdetector />
<input type="submit" ng-click="login()" value="Login"/>
<div ng-repeat="login in logins">{{ login }}</div>
</div>
</div>
Je pense que vous pourriez le faire en utilisant .setSelectionRange()
dans votre entrée. J'ai mis à jour votre exemple - voyez si c'est ce que vous vouliez: http://plnkr.co/edit/bIJAPPAzkzqLIDUxVlIy?p=preview
Remarque: setSelectionRange
n'est pas pris en charge par IE8 (voir https://developer.mozilla.org/en-US/docs/Web/API/HTMLInputElement.setSelectionRange ). Si vous devez prendre en charge IE <9, vous aurez besoin de chercher des cales.