【问题标题】:Unable to set focus on p:inputText in dataTable无法在 dataTable 中的 p:inputText 上设置焦点
【发布时间】:2020-02-18 19:39:55
【问题描述】:

我提供了一个按钮,用于在 dataTable 的 cellEditor 中添加新的 inputText。
我想将焦点自动设置在这个新的 inputText 上(单击按钮后),这样用户就可以开始输入数据而不必先单击单元格。

我的代码如下所示:

<p:commandButton action="#{myBean.addNewKeyword}" oncomplete="setFocus();" value="New keyword" onclick="editKeywords();" update='keywordForm' icon="fa fa-plus" />

<p:dataTable id="editKeywordsTbl" value="#{myBean.currentListKeywords}" var="keyWd" editMode="cell" editable="true" resizableColumns="true" widgetVar="editKeywords" rowIndexVar="index" >

    <p:ajax event="cellEdit" listener="#{myBean.onCellEditKeywords}" update="form" />
        <p:column headerText="Keyword" width="80">
            <p:cellEditor>
                 <f:facet name="output">
                      <h:outputText value="#{keyWd.keyword}" />
                 </f:facet>
                 <f:facet name="input">
                     <p:inputText value="#{keyWd.keyword}" placeholder="click here to edit" />
                 </f:facet>
            </p:cellEditor>
       </p:column>
</p:dataTable>

我尝试使用 javascript 在最后一个 inputText 上设置 fokus:

function setFocus() {
    var myTable = document.getElementById('editKeywordsTbl');
    var inputs = myTable.getElementsByTagName('input');
    var elemLast = inputs[inputs.length - 1];
    elemLast.focus();
};

很遗憾,这不起作用!
我应该提一下,这是在对话框中发生的。
非常感谢任何帮助。谢谢

澄清一下:我的问题是没有得到 inputText 的 id。
使用我的 Javascript,我可以访问此元素,因此我可以获得 id。

编辑:
我在我的 javascript 中尝试了elemLast.click();。新的 inputText 已打开以进行编辑,并具有一秒钟的焦点,然后迷路了。
我不明白为什么会这样。

Edit2 - 最小可重现示例:
Xhtml 页面:

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:p="http://primefaces.org/ui"
      xmlns:f="http://xmlns.jcp.org/jsf/core">
    <h:head>
        <title>Facelet Title</title>
    </h:head>

    <h:body>
        Hello from Facelets
        <br />

        <script type="text/javascript">
            function setFocus() {
                $(document).ready(function () {

                    var myTable = document.getElementById('editKeywordsTbl');
                    var inputs = myTable.getElementsByTagName('input');

                    var elemLast = inputs[inputs.length - 1];
                    console.log("elemLast: " + elemLast.id);
                    elemLast.click();
                    elemLast.focus();
                });
            }
        </script>

        <h:form id="keywordForm" prependId="false" >

            <p:commandButton action="#{myBean.addNewKeyword}" oncomplete="setFocus();" value="New keyword" update='keywordForm' />
            <br /><br /><br/>

            <p:dataTable id="editKeywordsTbl" value="#{myBean.currentListKeywords}" var="keyWd" editMode="cell" editable="true" resizableColumns="true" widgetVar="editKeywords" rowIndexVar="index" >

                <p:ajax event="cellEdit" listener="#{myBean.onCellEditKeywords}" />

                <p:column headerText="Keyword" width="80">
                    <p:cellEditor>
                        <f:facet name="output">
                            <h:outputText value="[click me to edit]" rendered="#{keyWd.name == ''}" />
                            <h:outputText value="#{keyWd.name}" rendered="#{keyWd.name != ''}" />
                        </f:facet>
                        <f:facet name="input">
                            <p:inputText value="#{keyWd.name}" required="true" requiredMessage="Enter a keyword!" placeholder="click here to edit" />
                        </f:facet>
                    </p:cellEditor>
                </p:column>
            </p:dataTable>
        </h:form>
    </h:body>
</html>

支持 bean:

package test;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.inject.Named;
import org.primefaces.event.CellEditEvent;
import test.entity.Keyword;

@Named
@SessionScoped
public class MyBean implements Serializable {

    private List<Keyword> currentListKeywords = new ArrayList<>();

    public void addNewKeyword() {
        Keyword ap = new Keyword();
        ap.setName("");

        currentListKeywords.add(ap);
    }

    public void onCellEditKeywords(CellEditEvent event) {
        Object newWord = event.getNewValue();
//        LOG.info("newWord: " + newWord);

        FacesContext context = FacesContext.getCurrentInstance();
        Keyword currentWord = context.getApplication().evaluateExpressionGet(context, "#{keyWd}", Keyword.class);

        if (newWord == null) {
            newWord = " ";
        }
        if (currentWord != null) {
            currentWord.setName((String) newWord);
        }
//        ejbFacade.editKeyword(currentWord);
    }

    public List<Keyword> getCurrentListKeywords() {
        return currentListKeywords;
    }

    public void setCurrentListKeywords(List<Keyword> currentListKeywords) {
        this.currentListKeywords = currentListKeywords;
    }
}

最后是关键字类:

package test.entity;

import java.io.Serializable;

public class Keyword implements Serializable {

    private String name;

    public Keyword(String name) {
        this.name = name;
    }

    public Keyword() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

【问题讨论】:

标签: primefaces jsf-2


【解决方案1】:

您可以使用一些 js 来实现,在您的按钮中添加 oncomplete="selectFocus()" 并使用 p:remoteCommand 调用您的 js 代码,如下所示:

 <p:remoteCommand name="selectFocus" oncomplete="dataEditableFocus('dataTableWidgetVar', false);" />

你的js必须是这样的:

dataEditableFocus = function (dataTableWidgetVar, hasRowIndex) {
    var row;
    var tb = $(document.getElementById(PF(dataTableWidgetVar).id));
    var multiple = $(tb).find('tr td.ui-selection-column');
    if ($(multiple).length === 0) {
        if (hasRowIndex) {
            row = $(tb).find('tr td.ui-editable-column:nth-child(2)');
        } else {
            row = $(tb).find('tr td.ui-editable-column:nth-child(1)');
        }
        $(row).last().find('input').click();
    } else {
        if (hasRowIndex) {
            row = $(tb).find('tr td.ui-editable-column:nth-child(3)');
        } else {
            row = $(tb).find('tr td.ui-editable-column:nth-child(2)');
        }
        $(row).last().parent().children().first().click();
        $(row).last().find('input').click();
    }
}

如果您在 dataTable 中添加一行 PF('dataTableWidgetVar').addRow(),则使用此代码 关注可编辑数据表中的第一个元素(如果您的表是selectionMode="multiple",代码会更复杂一些),您可以编辑代码以关注数据表中的每个元素。如果您的元素有RowIndex,请在调用函数中将其传递给true(表的方向可能会影响代码!)。

【讨论】:

  • 它不工作。同样的行为,新的 inputText 被打开进行编辑并获得焦点一秒钟然后迷路了。
  • @codyLine 您的代码中的某些内容可能会起作用。最好去掉多余的再试一次
  • 我提供了一个最小的可重现示例。请随时在上面测试您的代码。不到 5 分钟。
  • @codyLine 好的,如果可以的话,我今天就测试一下
  • 不更新,生成的inputText不会出现在datatable中。
【解决方案2】:

是的,我设法解决了这个问题。将addNewKeyword 按钮移动到单独的表单中并从inputText 中删除requiredrequiredMessage 属性解决了这个问题。不知道为什么!?

    <h:form >
          <p:commandButton action="#{myBean.addNewKeyword}" oncomplete="setFocus();" value="New keyword" update='keywordForm' />
          <br /><br /><br/>
    </h:form>

    <h:form id="keywordForm" prependId="false" >

         <p:dataTable id="editKeywordsTbl" value="#{myBean.currentListKeywords}" var="keyWd" editMode="cell" editable="true" resizableColumns="true" widgetVar="editKeywords" rowIndexVar="index" >

            <p:ajax event="cellEdit" listener="#{myBean.onCellEditKeywords}" />

            <p:column headerText="Keyword" width="80">
                 <p:cellEditor>
                     <f:facet name="output">
                          <h:outputText value="[click me to edit]" rendered="#{keyWd.name == ''}" />
                          <h:outputText value="#{keyWd.name}" rendered="#{keyWd.name != ''}" />
                     </f:facet>
                     <f:facet name="input">
                          <p:inputText value="#{keyWd.name}" placeholder="click here to edit" />
                     </f:facet>
                 </p:cellEditor>
            </p:column>
        </p:dataTable>
   </h:form>

感谢大家的贡献。

【讨论】:

    猜你喜欢
    • 2014-01-25
    • 1970-01-01
    • 2019-07-27
    • 1970-01-01
    • 1970-01-01
    • 2010-11-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多