为什么专注于文本框不是由AngularJS在twitter-bootstrap模式(弹出窗口)中设置的

时间:2013-07-11 17:13:35

标签: javascript twitter-bootstrap angularjs

我一直在努力实现这里建议的和其他类似的解决方案 How to set focus on input field?

PLUNKER我的代码具有非工作自动对焦功能。

HTML

  <body ng-controller='userNameController'>
  <button class="btn" id="enterUsernameBtn" href="#userNameModal" role="button" class="btn" data-toggle="modal" title="Enter Username" 
   ng-click="focusInput=true">Enter Username</button>


   <!-- UserName Modal -->
    <div id="userNameModal" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="userNameModalLabel"
         aria-hidden="true">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
            <h3 id="userNameModalLabel">Enter your username</h3>
        </div>


        <div class="modal-body">
            <div class="input-append">
                <input class="pull-left" id="userIdTextBox" type="text"
                ng-model="userName1" ng-minlength="1" ng-trim="true" focus-me="focusInput"/>
            </div>
        </div>


        <div class="modal-footer">
            <button class="btn" data-dismiss="{{whatToDismiss}}" aria-hidden="true" ng-click="submitUserName()">Submit</button>
        </div>
        </div>

  </body>

的JavaScript

var app = angular.module('abcApp',[]);

app.directive('focusMe', function($timeout) {
    return {
        scope: { trigger: '@focusMe' },
        link: function(scope, element) {
            scope.$watch('trigger', function(value) {
                if(value === "true") {
                    $timeout(function() {
                        element[0].focus();
                    });
                }
            });
        }
    };
});


app.controller('userNameController',function ($scope)
{
  $scope.whatToDismiss=''; // workaround not to close the modal if it is an invalid input
  $scope.focusInput=false;

  $scope.submitUserName= function ()
  {    
    if($scope.userName1===undefined || $scope.userName1==="")
      {
          alert("Invalid Input");
          return;
      }

    alert("username entered"+$scope.userName1);  
    $scope.whatToDismiss='modal';

  }
});  

没有一个解决方案适合我。每当模态打开时,我都会集中精力设置文本框,但是我不再获得userName1ng-model的值。实施focusMe指令userName1后总是未定义。

修改

试试这个 Can I use ng-model with isolated scope?

因为似乎ng-model不适用于上述解决方案

与此同时,任何人都会回答我的问题“如何在twitter-bootstrap模式中设置自动对焦到文本框,并且能够通过ng-model获得在该文本框中输入的值”请分享。

4 个答案:

答案 0 :(得分:9)

我修改了你的plunker http://plnkr.co/WKq83K,并创建了这个工作的plunker:http://plnkr.co/edit/fsBjsW?p=preview

更改如下:

使用focus-me,而不是focusMe

<input class="pull-left" id="userIdTextBox" type="text" ng-model="userName1"
 ng-minlength="1" ng-trim="true" focus-me="focusInput">

打开对话框时将focusInput设置为true

<button class="btn" id="enterUsernameBtn" href="#userNameModal" role="button"
 class="btn" data-toggle="modal" title="Enter Username" 
 ng-click="focusInput=true">Enter Username</button>

提交对话框时将其设置回false

$scope.submitUserName= function() {    
   $scope.focusInput = false;
   ...

或取消:

<button type="button" class="close" data-dismiss="modal" aria-hidden="true"
 ng-click="focusInput=false">x</button>

$timeout需要稍等片刻才能渲染模态。小于480的值似乎不起作用,所以我使用了更大的东西,700:

$timeout(function() {
   element.focus();
 }, 700);

答案 1 :(得分:2)

您在该帖子中找到的

focusMe指令并不意味着在没有进行某些更改的情况下与ng-model一起使用。该指令定义了隔离范围,因此ngModel不会向上传播到父控制器范围。

要解决这个问题,最简单的解决方案就是重新定义您的指令,不要使用单独的范围,并通过链接函数的attrs对象来获取focusMe属性值:

app.directive('_focusMe', function($timeout) {
  return function(scope, element, attrs) {
    scope.$watch(attrs.focusMe, function(value) {
      if(value) {
        $timeout(function() {
          element.focus();
        }, 20);
      }
    });
  };
});

PLUNKER

答案 2 :(得分:0)

我使用了以下网址Building dialog service using bootstrap modal来自定义我的提醒和确认框。这里我有一个默认情况下自动对焦ok按钮的情况。所以我使用了以下简单的指令,它对我有用,没有任何麻烦,希望它对任何人都有帮助。

myApp.directive('focusMe', function($timeout, $compile) {
    return {
        link: function (scope, element, attrs) {
            scope.$watch(attrs.focusMe, function(val) {
                // element.html(anyHtmlHere);
                // $compile(element.contents())(scope);
                $timeout(function() {
                    element[0].focus();
                }, 20);
            });
        }
    };
});

在这里,您可以使用注释部分

中的$ compile选项自定义元素的内部html

答案 3 :(得分:0)

我想尽可能简单地定义哪个输入字段会关注模态打开,因此我创建了一个名为$modal的{​​{1}}提供程序的扩展,并将其放在一个单独的模块中。现在每当我想在新打开的对话框中聚焦时,我只需写下:

modal

现在我唯一要做的就是使用function MyController(modal) { var modalInstance = modal.openExtended( { focus: "#categoryName", // ... more options } ); } 代替modal.openExtended并为选项提供$modal.open参数。

扩展名如下所示:

focus

请注意,您需要在应用中加入angular.module('components', ['ui.bootstrap']) .service('modal', function($modal, $timeout) { var extended = angular.extend( $modal ); $modal.openExtended = function( modalOptions ) { var modalInstance = $modal.open( modalOptions ); if ( typeof( modalOptions.focus ) != "undefined" ) { modalInstance.opened.then( function() { $timeout( function() { $( modalOptions.focus ).focus(); // The interval of 100 millis below is somewhat arbitrary. // Use something higher if the focus doesn't always work }, 100 ); }); } return modalInstance; }; return extended; }); 模块:

components