Невозможно установить фокус на p: inputText в dataTable - PullRequest
1 голос
/ 22 октября 2019

Я предоставляю кнопку для добавления нового inputText внутри cellEditor в dataTable.
Я хотел бы установить фокус на этот новый 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>

Я пытался установить фокус на последнем inputText с помощью javascript:

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

К сожалению, это не работает!
Я должен упомянуть, что это происходит внутри диалога.
Любая помощь очень ценится. Спасибо

Для пояснения: Моя проблема не заключается в получении идентификатора inputText.
С моим Javascript у меня есть доступ к этому элементу, и поэтому я могу получить идентификатор.

Редактировать:
Я пытался elemLast.click(); в моем JavaScript. Новый 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>

Поддерживающий компонент:

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;
    }
}

enter image description here

Ответы [ 2 ]

0 голосов
/ 24 октября 2019

Да, мне удалось решить эту проблему. Перемещение кнопки addNewKeyword в отдельную форму и удаление атрибута required и requiredMessage из inputText решило проблему. Я не знаю почему !?

    <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>

Спасибо всем за вклад.

0 голосов
/ 23 октября 2019

Вы можете сделать это с некоторыми 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();
    }
}

с этим кодом, если вы добавляете строку в вашу таблицу данных с PF('dataTableWidgetVar').addRow() фокусом, переходите к первому элементу в редактируемой таблице данных (если ваша таблица selectionMode="multiple", код имеет некоторые сложности), вы можете редактировать коддля сосредоточения внимания на каждом элементе в datatable. если ваши элементы имеют RowIndex, передайте его значение true в функции invoke (изменение таблицы может повлиять на код!).

...