如何自动聚焦第一个骨干表单输入字段?

时间:2013-12-08 19:26:28

标签: backbone.js focus marionette backbone-views backbone-forms

以下屏幕截图显示了登录和注册的组合表单:

Backbone Form

以下模块用于呈现AuthView

MyApp.module("User", function(User, App, Backbone, Marionette, $, _) {

  User.AuthView = Marionette.ItemView.extend({

    className: "reveal-modal",
    template: "user/auth",

    ui: {
      signInForm: "#signin-form",
      signUpForm: "#signup-form"
    },

    events: {
      "focus input": "onFocus"
    },

    onFocus: function() {
      console.log("Some input field has received focus.");
    },

    onRender: function() {  
      this.signInForm = new Backbone.Form({
        schema: {
          signInEmail: { 
            type: "Text", 
            title: "E-Mail address"
          },
          signInPassword: { 
            type: "Password", 
            title: "Password"
          }
        }
      }).render();
      this.ui.signInForm.prepend(this.signInForm.el);

      this.signUpForm = new Backbone.Form({
        schema: {
          signUpEmail: { 
            type: "Text", 
            title: "E-Mail address"
          },
          signUpPassword: { 
            type: "Password", 
            title: "Password"
          },
          signUpPasswordConfirmation: { 
            type: "Password", 
            title: "Password confirmation"
          }
        }
      }).render();
      this.ui.signUpForm.prepend(this.signUpForm.el);
    }

  });
});

如何渲染每个子表单中的第一个字段?对于signInEmail,第一个字段为signInFormsignUpEmailsignUpForm。 我试着听focus input个事件。当我点击其中一个输入字段时触发这样的事件,而不是之前。


与此同时,受到当前答案的启发,我提出了以下帮助函数:

focusFirstFormField: function(form) {
  if (_.isUndefined(form)) {
    throw "IllegalStateException: Form is undefined."
  }
  // TODO: AuthView does not focus first sign-in field.
  var firstInput = form.find(':input:first');
  if (_.isObject(firstInput)) {
    if (firstInput.length > 0) {
      firstInput = firstInput[0];
    }
    else {
      throw "IllegalStateException: Form find returns an empty jQuery object."
    }
  }
  _.defer(function() {
    firstInput.focus();
  });
 }

但仍需要改进。

4 个答案:

答案 0 :(得分:6)

事件对象是DOM事件,通常由用户触发,因此在这种情况下不是您可能想要使用的事件。

如果我正确理解你,你想把焦点放在每个表格的第一个输入中但是因为你一次只能关注一件事而且他们在一起渲染你必须选择一个或另一个。

最简单的选择是在onRender的末尾添加另一行,专注于输入。如果您的输入正在生成如下输入:

<input type="text" name="signInEmail">

然后你可以添加:

this.$('[name=signInEmail]').focus();

如果不是,你将不得不更改选择器。$(xxxx).focus()以适应。

答案 1 :(得分:4)

您可以使用视图的onDomRefresh事件。它将在视图渲染和Dom刷新后触发。

onDomRefresh: function() {
  this.focusFirstInput();
};

focusFirstInput: function() {
  this.$(':input:visible:enabled:first').focus();
};

此解决方案适用于一般情况。但是,如果您使用的是Bootstrap,请注意。我不能在那里得到这项工作。相反,我在字段中设置autofocus: 'autofocus'并且它可以正常工作。

答案 2 :(得分:1)

您可以将其添加到onRender方法。

this.ui.signInForm.find('input[type=text]:first').focus();
this.ui.signUpForm.find('input[type=text]:first').focus();

答案 3 :(得分:1)

在我所做的onRender方法上:

$(this.el).find(':input[autofocus]').focus();

我将autofocus=""标志添加到我的HTML节点上。这适用于刷新。