primefaces

PrimeFaces autoComplete looses focus inside a dataTable


I am using a autoComplete inside a dataTable. When I open the dropdown, the autoComplete looses focus and I can not enter anything. If I am using the autoComplete outside a dataTable, the autoComplete keeps the focus, I can open the dropdown and enter values.

I am using PrimeFaces v15.0.4 and I made an example based on the PrimeFaces Test project:

<h:form>
    <p:dataTable
        style="width: 99%"
        selectionRowMode="none"
        selectionDisabled="true"
        value="#{autoCompleteInDataTableBean.container}">

            <p:column headerText="Container">
                <p:autoComplete placeholder="Select something"
                    size="27"
                    multiple="true"
                    dropdown="true"
                    var="value"
                    itemLabel="#{value}"
                    itemValue="#{value}"
                    forceSelection="true"
                    value="#{autoCompleteWithMultipleSelectionBean.selection}"
                    completeMethod="#{autoCompleteWithMultipleSelectionBean.complete}" />
            </p:column>
    </p:dataTable>

    <p:autoComplete placeholder="Select something"
        size="27"
        multiple="true"
        dropdown="true"
        var="value"
        itemLabel="#{value}"
        itemValue="#{value}"
        forceSelection="true"
        value="#{autoCompleteWithMultipleSelectionBean.selection}"
        completeMethod="#{autoCompleteWithMultipleSelectionBean.complete}" />
</h:form>
import java.io.Serializable;
import java.util.List;
import java.util.stream.Stream;

import jakarta.annotation.PostConstruct;
import jakarta.faces.view.ViewScoped;
import jakarta.inject.Named;

import org.apache.commons.lang3.StringUtils;

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.Setter;

@Setter
@Getter
@Named
@ViewScoped
public class AutoCompleteInDataTableBean implements Serializable {
    @NoArgsConstructor
    @AllArgsConstructor
    @Getter
    @Setter
    public static final class Container {
        public List<String> values;
    }
    private List<Container> container;

    @PostConstruct
    public void init() {
       container = List.of(new Container(List.of("ABD value0", "ABC value1")));
    }

    public List<String> complete(final String query) {
        return Stream.of("ABC value0", "ABC value1", "ABC value2", "ABC value3",
                "DEF value0", "DEF value1", "DEF value2", "DEF value3",
                "GHI value0", "GHI value1", "GHI value2", "GHI value3")
                .filter(v -> StringUtils.containsIgnoreCase(v, query))
                .toList();
    }
}

The autoComplete outside the dataTable works fine. I tried to set selectionRowMode to none and disable the selection on the dataTable, but the behaviour is still the same.

Thanks in advance for any help.

Edit

As suggested I opened a GitHub Issue

https://github.com/primefaces/primefaces/issues/14018


Solution

  • MonkeyPatch below.. this is fixed in 15.0.7

    if (PrimeFaces.widget.AutoComplete) {
      PrimeFaces.widget.AutoComplete.prototype.bindDropdownEvents = function() {
        var $this = this;
    
        PrimeFaces.skinButton(this.dropdown);
    
        this.dropdown.on("mouseup", function() {
          if ($this.active) {
            $this.searchWithDropdown();
            PrimeFaces.queueTask(() => {
              $this.input.trigger('focus');
            }, 1);
          }
        }).on("keyup", function(e) {
          if (PrimeFaces.utils.isActionKey(e)) {
            $this.searchWithDropdown();
            $this.input.trigger('focus');
            e.preventDefault();
            e.stopPropagation();
          }
        });
      }
    }