0

The Goal: To provide a series of text fields where when you have it selected and press the enter key it will either add a new text field (if you press enter in the last field) or focus on the next field (if you press enter on any other field).

The Idea: Using a directive that detects enter key presses will trigger a callback to the original controller that will be able to perform the necessary tasks. Ideally this directive will be able to use elsewhere for other actions other than the next / new text fields goal stated above.

The Problem: I've written the directive that will detect the enter key press and will then make a call to the callback function WITH the event data (used to detect which field was active when pressing the enter key). This works great! However... when the scope: [method: '&ngEnter'] is on the directive it kills all relationship between the text field and the controller (??). Therefore all textfields are blank (yet the other sub data found elsewhere (anywhere but the input) function properly, so the data itself is intact and correct, but when applied to the textfield it acts all screwy.

The Code: Found Below...

Directive: ng_enter.coffee

angular.module('app.common').directive "ngEnter", ['$parse', ($parse) ->
  restrict: 'A'
  scope:
    method: '&ngEnter'
  link: (scope, element, attrs) ->
    expressionHandler = scope.method()
    element.bind "keydown keypress", (event) ->
      if event.which is 13
        event.preventDefault()
        scope.$apply ->
          expressionHandler(event)
]

my_view.haml

.item-list.sub-item-list.bordered-background
  .item-row(ng-repeat='sub in categoryEditor.categorizations' ng-hide='sub._destroy')
    %div
      %input.left{type: 'text', "ng-model"=>"sub.name", style: 'width: 85%; margin: 0 0 0 1px;', 'ng-enter' => 'subitemEnter'}
      %i.icon-large.right.icon-remove{"ng-click"=>"removeSubItem(sub)", title: "{{sub.name}}"}

my_controller.coffee

angular.module('app.admin.controllers').controller 'MyControllerCtrl', ['$scope', ($scope) ->
  $scope.categoryEditor = {...}
  $scope.subitemEnter = (event) ->
    console.log "subitemEnter() Triggered"
    console.log event

Update: It appears that scope is being overwritten, and i must find a way to solve this without explicitly declaring scope in my directive.

Michael Lynch
  • 1,743
  • 15
  • 27
  • Why don't you look at ngKeypress http://docs.angularjs.org/api/ng.directive:ngKeypress – Chandermani Oct 14 '13 at 16:50
  • Creating a scope object in directive creates an isolated scope, which does not work well with ng-model. – Chandermani Oct 14 '13 at 16:51
  • @Chandermani: I didnt use ngKeyPress becuase I Originally Followed: http://stackoverflow.com/questions/17470790/how-to-use-a-keypress-event-in-angularjs – Michael Lynch Oct 14 '13 at 17:33
  • @Chandermani It also appears that I do not have access to `ng-keypress` in my current version of angular. But looking into that lead me to Angular UI Utils that provided a simple / easy solution. Thanks. – Michael Lynch Oct 14 '13 at 18:12

1 Answers1

0

Installing Angular UI Utils, I was able to get access to ui-keypress that provides a easy way of performing callbacks on various keypress events. The following code is the solution.

View (.haml):

%input{type: 'text', "ng-model"=>"sub.name", 'ui-keypress' => "{13:'subItemEnterPress($event)'}"}

Controller (.coffee):

  $scope.subItemEnterPress = (event) ->
    event.preventDefault()
    inputs = $(event.target).closest('.item-list').find('input')
    if event.target == _.last(inputs)
      $scope.addSubItem()
    else
      $(inputs[ _.indexOf(inputs, event.target) + 1 ]).focus()
Michael Lynch
  • 1,743
  • 15
  • 27