2013-07-04 55 views
359

我想在下面的文本框中看到Enter鍵按下事件。爲了更清楚地說明,我使用了一個ng-repeat來填充tbody。下面是HTML:如何在AngularJS中使用按鍵事件?

<td><input type="number" id="closeqty{{$index}}" class="pagination-right closefield" 
    data-ng-model="closeqtymodel" data-ng-change="change($index)" required placeholder="{{item.closeMeasure}}" /></td> 

這是我的模塊:

angular.module('components', ['ngResource']); 

我使用的資源來填充表和我的控制器代碼:

function Ajaxy($scope, $resource) { 
//controller which has resource to populate the table 
} 
+1

是一個表單內的輸入? – callmekatootie

+1

不..它在一張桌子! –

回答

761

您需要添加一個directive,像這樣:

Javascript

app.directive('myEnter', function() { 
    return function (scope, element, attrs) { 
     element.bind("keydown keypress", function (event) { 
      if(event.which === 13) { 
       scope.$apply(function(){ 
        scope.$eval(attrs.myEnter); 
       }); 

       event.preventDefault(); 
      } 
     }); 
    }; 
}); 

HTML

<div ng-app="" ng-controller="MainCtrl"> 
    <input type="text" my-enter="doSomething()">  
</div> 
+27

請你能解釋一下這段代碼嗎? :) –

+7

@DerekAdair該指令綁定到它所屬元素的'keydown'和'keypress'事件。當接收到事件時,提供的表達式將在'$ apply'塊內進行評估。 –

+7

更安全的定義這樣的關鍵:'''var key = typeof event.which ===「undefined」? event.keyCode:event.which;'''只要event.which不被每個瀏覽器使用。在這裏看到評論:http://stackoverflow.com/a/4471635/2547632 – Gabriel

316

另一種方法是使用標準的指令ng-keypress="myFunct($event)"

然後在你的控制器,你可以有:

... 

$scope.myFunct = function(keyEvent) { 
    if (keyEvent.which === 13) 
    alert('I am an alert'); 
} 

... 
+16

爲了節省一些時間,'ng-keypress'似乎不是角度1.0.x的一部分,'ui-keypress'(略有不同的調用語義)可用:http:// angular-ui。 github.io/ui-utils/ – Cebjyre

+8

它不適用於像ESC或ALT這樣的'keycode'。 – oliholz

+0

我認爲上面的註釋針對的是不同的答案。 (僅供參考) – Cornelius

0

的代碼的例子我爲我的項目做的。 基本上你給你的實體添加標籤。 想象一下,你有輸入文本,在進入標籤名稱你下拉菜單中預裝的標籤可供選擇,您瀏覽帶有箭頭和與選擇輸入:

HTML + AngularJS V1.2.0-rc.3

<div> 
     <form ng-submit="addTag(newTag)"> 
      <input id="newTag" ng-model="newTag" type="text" class="form-control" placeholder="Enter new tag" 
        style="padding-left: 10px; width: 700px; height: 33px; margin-top: 10px; margin-bottom: 3px;" autofocus 
        data-toggle="dropdown" 
        ng-change="preloadTags()" 
        ng-keydown="navigateTags($event)"> 
      <div ng-show="preloadedTags.length > 0"> 
       <nav class="dropdown"> 
        <div class="dropdown-menu preloadedTagPanel"> 
         <div ng-repeat="preloadedTag in preloadedTags" 
          class="preloadedTagItemPanel" 
          ng-class="preloadedTag.activeTag ? 'preloadedTagItemPanelActive' : '' " 
          ng-click="selectTag(preloadedTag)" 
          tabindex="{{ $index }}"> 
          <a class="preloadedTagItem" 
           ng-class="preloadedTag.activeTag ? 'preloadedTagItemActive' : '' " 
           ng-click="selectTag(preloadedTag)">{{ preloadedTag.label }}</a> 
         </div> 
        </div> 
       </nav> 
      </div> 
     </form> 
    </div> 

Controller.js

$scope.preloadTags = function() { 
    var newTag = $scope.newTag; 
    if (newTag && newTag.trim()) { 
     newTag = newTag.trim().toLowerCase(); 

     $http(
      { 
       method: 'GET', 
       url: 'api/tag/gettags', 
       dataType: 'json', 
       contentType: 'application/json', 
       mimeType: 'application/json', 
       params: {'term': newTag} 
      } 
     ) 
      .success(function (result) { 
       $scope.preloadedTags = result; 
       $scope.preloadedTagsIndex = -1; 
      } 
     ) 
      .error(function (data, status, headers, config) { 
      } 
     ); 
    } else { 
     $scope.preloadedTags = {}; 
     $scope.preloadedTagsIndex = -1; 
    } 
}; 

function checkIndex(index) { 
    if (index > $scope.preloadedTags.length - 1) { 
     return 0; 
    } 
    if (index < 0) { 
     return $scope.preloadedTags.length - 1; 
    } 
    return index; 
} 

function removeAllActiveTags() { 
    for (var x = 0; x < $scope.preloadedTags.length; x++) { 
     if ($scope.preloadedTags[x].activeTag) { 
      $scope.preloadedTags[x].activeTag = false; 
     } 
    } 
} 

$scope.navigateTags = function ($event) { 
    if (!$scope.newTag || $scope.preloadedTags.length == 0) { 
     return; 
    } 
    if ($event.keyCode == 40) { // down 
     removeAllActiveTags(); 
     $scope.preloadedTagsIndex = checkIndex($scope.preloadedTagsIndex + 1); 
     $scope.preloadedTags[$scope.preloadedTagsIndex].activeTag = true; 
    } else if ($event.keyCode == 38) { // up 
     removeAllActiveTags(); 
     $scope.preloadedTagsIndex = checkIndex($scope.preloadedTagsIndex - 1); 
     $scope.preloadedTags[$scope.preloadedTagsIndex].activeTag = true; 
    } else if ($event.keyCode == 13) { // enter 
     removeAllActiveTags(); 
     $scope.selectTag($scope.preloadedTags[$scope.preloadedTagsIndex]); 
    } 
}; 

$scope.selectTag = function (preloadedTag) { 
    $scope.addTag(preloadedTag.label); 
}; 

CSS +引導V2.3.2

.preloadedTagPanel { 
    background-color: #FFFFFF; 
    display: block; 
    min-width: 250px; 
    max-width: 700px; 
    border: 1px solid #666666; 
    padding-top: 0; 
    border-radius: 0; 
} 

.preloadedTagItemPanel { 
    background-color: #FFFFFF; 
    border-bottom: 1px solid #666666; 
    cursor: pointer; 
} 

.preloadedTagItemPanel:hover { 
    background-color: #666666; 
} 

.preloadedTagItemPanelActive { 
    background-color: #666666; 
} 

.preloadedTagItem { 
    display: inline-block; 
    text-decoration: none; 
    margin-left: 5px; 
    margin-right: 5px; 
    padding-top: 5px; 
    padding-bottom: 5px; 
    padding-left: 20px; 
    padding-right: 10px; 
    color: #666666 !important; 
    font-size: 11px; 
} 

.preloadedTagItem:hover { 
    background-color: #666666; 
} 

.preloadedTagItemActive { 
    background-color: #666666; 
    color: #FFFFFF !important; 
} 

.dropdown .preloadedTagItemPanel:last-child { 
    border-bottom: 0; 
} 
+2

我認爲這是一個討厭的解決方案。控制器不應該像按鍵一樣處理UI事物。 –

+5

這個答案包含了很多「噪音」,以一種說話的方式,包含大量的標記 - 就我所能看到的一目瞭然 - 與手頭的實際問題無關。壓縮答案中的代碼可能更簡潔/有用,並在gist/jsfiddle/plnkr中提供完整的示例。 – Cornelius

+1

@MartinAndersen,應該在哪裏按鍵處理一個角度的應用程序? – Emanegux

2

您也可以將其應用於父元素上的控制器。通過按向上/向下箭頭鍵可以使用此示例來突出顯示錶格中的一行。

app.controller('tableCtrl', [ '$scope', '$element', function($scope, $element) { 
    $scope.index = 0; // row index 
    $scope.data = []; // array of items 
    $scope.keypress = function(offset) { 
    console.log('keypress', offset); 
    var i = $scope.index + offset; 
    if (i < 0) { i = $scope.data.length - 1; } 
    if (i >= $scope.data.length) { i = 0; } 
    }; 
    $element.bind("keydown keypress", function (event) { 
    console.log('keypress', event, event.which); 
    if(event.which === 38) { // up 
     $scope.keypress(-1); 
    } else if (event.which === 40) { // down 
     $scope.keypress(1); 
    } else { 
     return; 
    } 
    event.preventDefault(); 
    }); 
}]); 


<table class="table table-striped" ng-controller="tableCtrl"> 
<thead> 
    <tr> 
     <th ng-repeat="(key, value) in data[0]">{{key}}</th> 
    </tr> 
</thead> 
<tbody> 
    <tr ng-repeat="row in data track by $index" ng-click="draw($index)" ng-class="$index == index ? 'info' : ''"> 
     <td ng-repeat="(key, value) in row">{{value}}</td> 
    </tr> 
</tbody> 
</table> 

98

另一種簡單的選擇:

<input ng-model="edItem" type="text" 
    ng-keypress="($event.which === 13)?foo(edItem):0"/> 

而NG-UI選擇:

<input ng-model="edItem" type="text" ui-keypress="{'enter':'foo(edItem)'}"/> 
+9

ng-ui它是不明確的,而應該說「UI.Utils」或共享鏈接:http://angular-ui.github.io/ui-utils/ –

+0

ui-utils似乎已被棄用 – cafesanu

0

我有點晚了..但我發現了一個簡單的解決方案使用auto-focus ..這可能是有用的按鈕或其他彈出時dialog

<button auto-focus ng-click="func()">ok</button>

,如果你想按按鈕on Space或Enter鍵點擊這應該是罰款。

+0

它的問題按回車並做點什麼。 – BlaShadow

3

試圖

ng-keypress="console.log($event)" 
ng-keypress="alert(123)" 

什麼也沒做對我來說。

Strangley樣本https://docs.angularjs.org/api/ng/directive/ngKeypress,其中ng-keypress =「count = count + 1」,起作用。

我找到了一個備用解決方案,它按Enter鍵調用按鈕的ng鍵。

<input ng-model="..." onkeypress="if (event.which==13) document.getElementById('button').click()"/> 
<button id="button" ng-click="doSomething()">Done</button> 
+0

'ng-keypress =「console.log('foo')」'對我也不起作用,但是如果你使用'ng-keypress =「fooMethod()」'並在你的控制器中'$ scope.fooMethod = function () { console.log('fooMethod called'); ''''' }'確實有效。 – GraehamF

2

這是對EpokK答案的擴展。

我有同樣的問題,在輸入字段上輸入時,必須調用範圍函數。不過,我也希望將輸入字段的值傳遞給指定的函數。這是我的解決方案:

app.directive('ltaEnter', function() { 
return function (scope, element, attrs) { 
    element.bind("keydown keypress", function (event) { 
     if(event.which === 13) { 
      // Create closure with proper command 
      var fn = function(command) { 
      var cmd = command; 
      return function() { 
       scope.$eval(cmd); 
      }; 
      }(attrs.ltaEnter.replace('()', '("'+ event.target.value +'")')); 

      // Apply function 
      scope.$apply(fn); 

      event.preventDefault(); 
     } 
    }); 
}; 

});

在HTML中使用如下:

<input type="text" name="itemname" lta-enter="add()" placeholder="Add item"/> 

榮譽給EpokK他的回答。

+0

'' – aycanadal

139

我只用角內建指令最簡單的方法:

ng-keypressng-keydownng-keyup

通常,我們希望爲已經通過ng-click處理的東西添加鍵盤支持。

例如:

<a ng-click="action()">action</a> 

現在,讓我們添加鍵盤支持。

觸發通過回車鍵:

<a ng-click="action()" 
    ng-keydown="$event.keyCode === 13 && action()">action</a> 

按空格鍵:

<a ng-click="action()" 
    ng-keydown="$event.keyCode === 32 && action()">action</a> 

用空格或回車鍵:

<a ng-click="action()" 
    ng-keydown="($event.keyCode === 13 || $event.keyCode === 32) && action()">action</a> 

,如果你是現代的瀏覽器

<a ng-click="action()" 
    ng-keydown="[13, 32].includes($event.keyCode) && action()">action</a> 

關於keyCode的更多信息:
keyCode已棄用但支持良好的API,您可以在支持的瀏覽器中使用$ evevt.key。
見多https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key

+1

祕密是條件之前要執行的方法$ event.which === 13 && action() - 謝謝! – wbeange

+1

'$ event.which'不適合我,但我發現'$ event.keyCode'正在工作。 – abimelex

+0

event.which在keydown和keyup的IE <9中未定義。 –

17

這是我想通了,當我建立一個應用程序有類似的要求, 它不需要寫一個指令,它是相對簡單的告訴它做什麼:

<input type="text" ng-keypress="($event.charCode==13)?myFunction():return" placeholder="Will Submit on Enter"> 
+3

簡單而有效。 – Xplouder

1

這是怎麼回事?:

<form ng-submit="chat.sendMessage()"> 
    <input type="text" /> 
    <button type="submit"> 
</form> 

現在當你在你的輸入中寫入一些東西后按回車鍵,表格就知道如何處理它了。

+0

「chat.sendMessage()」定義的方式/位置 –

14

您可以使用ng-keydown =「myFunction($ event)」作爲屬性。

<input ng-keydown="myFunction($event)" type="number"> 

myFunction(event) { 
    if(event.keyCode == 13) { // '13' is the key code for enter 
     // do what you want to do when 'enter' is pressed :) 
    } 
} 
0

這裏是我的指令:

mainApp.directive('number', function() { 
    return { 
     link: function (scope, el, attr) { 
      el.bind("keydown keypress", function (event) { 
       //ignore all characters that are not numbers, except backspace, delete, left arrow and right arrow 
       if ((event.keyCode < 48 || event.keyCode > 57) && event.keyCode != 8 && event.keyCode != 46 && event.keyCode != 37 && event.keyCode != 39) { 
        event.preventDefault(); 
       } 
      }); 
     } 
    }; 
}); 

用法:

<input number /> 
0

可以使用NG-的keydown,NG-KEYUP,NG-按本等。

通過靶向功能:

<input type="text" ng-keypress="function()"/> 

,或者如果你有一個condion比如當他按下Esc鍵即可(圖27是用於逃生的關鍵 代碼)

<form ng-keydown=" event.which=== 27?cancelSplit():0"> 
.... 
</form> 
3

html

<textarea id="messageTxt" 
    rows="5" 
    placeholder="Escriba su mensaje" 
    ng-keypress="keyPressed($event)" 
    ng-model="smsData.mensaje"> 
</textarea> 

controller.js

$scope.keyPressed = function (keyEvent) { 
    if (keyEvent.keyCode == 13) { 
     alert('presiono enter'); 
     console.log('presiono enter'); 
    } 
}; 
0

我認爲使用document.bind是有點更優雅

constructor($scope, $document) { 
    var that = this; 
    $document.bind("keydown", function(event) { 
    $scope.$apply(function(){ 
     that.handleKeyDown(event); 
    }); 
    }); 
} 

要獲得文件到控制器構造函數:

controller: ['$scope', '$document', MyCtrl] 
0
<!DOCTYPE html> 
<html> 
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script> 
<body> 
<div ng-app="myApp" ng-controller="myCtrl"> 
Informe your name:<input type="text" ng-model="pergunta" ng-keypress="pressionou_enter($event)" ></input> 
<button ng-click="chamar()">submit</button> 
<h1>{{resposta}}</h1> 
</div> 
<script> 
var app = angular.module('myApp', []); 
//create a service mitsuplik 
app.service('mitsuplik', function() { 
    this.myFunc = function (parametro) { 
     var tmp = ""; 
     for (var x=0;x<parametro.length;x++) 
      { 
      tmp = parametro.substring(x,x+1) + tmp; 
      } 
     return tmp; 
    } 
}); 
//Calling our service 
app.controller('myCtrl', function($scope, mitsuplik) { 
    $scope.chamar = function() { 
     $scope.resposta = mitsuplik.myFunc($scope.pergunta); 
    }; 
    //if mitsuplik press [ENTER], execute too 
    $scope.pressionou_enter = function(keyEvent) { 
      if (keyEvent.which === 13) 
       { 
       $scope.chamar(); 
       } 

    } 
}); 
</script> 
</body> 
</html> 
0

如何只

<input (keyup.enter)="doWhatYouWant()"> 
相關問題