2013-07-30 3 views
4

Я написал специальную директиву для проверки полей формы. Когда выполняются определенные критерии (т. Е. Он грязный и действительный), я хочу автоматически настроить фокус на следующий элемент ввода. Это требование от моих пользователей, так что они могут наиболее эффективно перемещаться по формам.AngularJS: переход к следующему элементу ввода после успешной проверки

Упрощенная директива выглядит следующим образом:

directive('custom', ['$parse', function($parse) { 
    return { 
     restrict: 'A', 
     require: ['ngModel', '^ngController'], 
     link: function(scope, element, attrs, ctrls) { 
      var model=ctrls[0], form=ctrls[1]; 

      scope.next = function(){ 
       return model.$valid 
      } 

      scope.$watch(scope.next, function(newValue, oldValue){ 
       if (newValue && model.$dirty){ 
        ??? 
       } 
      }) 

Теперь мой вопрос: как я могу определить - следующий входной элемент (который является следующим родственным) или, возможно, через TabIndex - и сосредоточиться на это без использования JQuery?

Для меня в настоящее время неясно, как перейти к следующему элементу ввода из доступных атрибутов «scope» или «element» без Jquery; и JQlite не имеет метода «фокуса». В принципе, мне нужна рабочая замена ??? в моем коде.

Любая помощь очень ценится. Благодаря Юргена

+0

Может быть, следующее может быть полезным: http://stackoverflow.com/questions/18086865/angularjs-move-focus-to-next-control-on-enter –

ответ

5

Вы можете использовать [0], чтобы получить лежащий input элемент (который имеет focus() функцию) из угловой/jqLite объект (который нет).

app.directive('custom', ['$parse', function($parse) { 
    return { 
     restrict: 'A', 
     require: ['ngModel'], 
     link: function(scope, element, attrs, ctrls) { 
      var model=ctrls[0], form=ctrls[1]; 

      scope.next = function(){ 
       return model.$valid; 
      } 

      scope.$watch(scope.next, function(newValue, oldValue){ 
       if (newValue && model.$dirty) 
       { 
        var nextinput = element.next('input'); 
        if (nextinput.length === 1) 
        { 
         nextinput[0].focus(); 
        } 
       } 
      }) 
     } 
    } 
}]) 

http://jsfiddle.net/Y2XLA/

+0

в первый раз работает как исключение, если длина равна 3. Но опять же, когда мы пытаемся войти в текстовое поле, оно не работает как исключенное.И, кроме того, в последнем текстовом поле он позволяет вводить более 3-х символов в самом внутреннем времени. – Arun

+0

Он работает в соответствии с назначением: когда состояние ввода изменяется с недействительного на допустимое, следующий вход получает фокус. Как и следовало ожидать, изменение более раннего (действительного) текстового поля ничего не делает, если вы не сделаете недействительным этот ввод первым (например, удалив все). В примере допустимость minlength = 3, поэтому допустимо более 3 символов (и, кроме того, в первую очередь не упоминается о некорректном вводе недопустимого ввода.) – towr

+0

извините за недоразумение спасибо towr :) – Arun

0

AngularJS уже содержит облегченную версию JQuery, так что вы можете также использовать его ... http://docs.angularjs.org/api/angular.element

Вы могли бы попробовать что-то вроде этого:

element.next(). фокус()

+0

Я подробно мой вопрос – schacki

+0

Я попробовал element.next(), но это, похоже, не сработало. Morevoer, angular.element не имеет метода фокусировки. – schacki

+0

Может быть, '$ (element) .next(). Focus()' будет работать. 'focus()' - простой метод javascript. – mrt

3

element.next().focus() не может работать, если у вас есть сложная форма и вход вложены в различные дивы. Я закончил писать эту директиву (здесь я переместить фокус на Enter, но может быть адаптирован к любому событию):

.directive('enterToTab', function($timeout) { 
    return { 
    restrict: 'A', 
    link: function(scope, element, attrs) { 
     var procAttr = 'data-ett-processed'; 

     $timeout(function() { // Use $timeout to run the directive when the DOM is fully rendered 
     var formElements = element[0].querySelectorAll('input:not([' + procAttr + '="true"]), select:not([' + procAttr + '="true"]), textarea:not([' + procAttr + '="true"])'); 

     // Run through all elements in form 
     var formElementsLength = formElements.length; 
     for (var i = 0; i < formElementsLength; i++) {   // Add tabindex attribute 
      formElements[i].setAttribute('tabindex', i + 1); 

      // Go to next element on Enter key press 
      formElements[i].addEventListener('keypress', function(event) { 
      if (event.keyCode === 13) { // Enter 
       // Prevent Angular from validating all the fields and submitting 
       if (event.target.tagName !== 'TEXTAREA') { // Not on textarea, otherwise not possible to add new line 
       event.stopPropagation(); 
       event.preventDefault(); 
       } 

       var nextIndex = parseInt(event.target.getAttribute('tabindex')) + 1; 

       // Move focus to next element 
       // TODO: find next visible element 
       var nextElem = element[0].querySelector('[tabIndex="' + (nextIndex) + '"]'); 

       if (nextElem) { 
       nextElem.focus(); 
       } 
      } 
      }); 
      formElements[i].setAttribute(procAttr, true); // Add attribute to prevent adding 2 listeners on same element 
     } 
     }); 
    } 
    }; 
}); 
+0

Лот полезной 'gotcha' предотвращено в этом коде: thumbsup: –

1
  1. событие должно быть в HTML-компоненте (keypress) = "keyFocus($event)"
  2. Метод shoulb быть как .ts файл ,

    keyFocus(input1){ input1.srcElement.nextElementSibling.focus(); }

Смежные вопросы