Reset value to null in primefaces autocomplete event

我只是一个虾纸丫 提交于 2019-12-05 00:15:04

问题


I have an autocomplete event that fires correctly once a value is selected. I want another event to fire once I erase the value in the textbox and reset the value to null. I was thinking of using the onChange attribute but I was having issues so I reverted back to my original code.

<p:autoComplete id="deviceAuto" dropdown="true" scrollHeight="250" 
                value="#{summaryReportController.device.nickname}" 
                forceSelection="true" 
                completeMethod="#{summaryReportController.deviceComplete}">
    <p:ajax event="itemSelect" 
        listener="#{summaryReportController.handleDeviceSelect}" 
        update="printThis" />  
</p:autoComplete> 
public void handleDeviceSelect(SelectEvent event) {
    String deviceSelect = event.getComponent().getId();
    if (deviceSelect.equalsIgnoreCase("deviceAuto")) {
        Device selectedDevice = deviceMgr.getDevicebyNickname(device.getNickname());
        setDevice(selectedDevice);
    }
    updateInterface();
}

回答1:


When you modify the text content of the AutoComplete textfield, the search method (aka. completeMethod) will be called on the backing bean. You can reset the value to null there if you get an empty string.

Backing Bean

// insert getter and setter for the device property ...

/** Search for devices by name */
public List<String> deviceComplete(String search) {
    if (StringUtils.isBlank(search)) {
        setDevice(null);  // textfield was cleared, reset device value!
        return Collections.emptyList();
    } else {
        // search for devices ...
        return deviceNames;
    }
}

Note that I used Apache Commons StringUtils.isBlank(String) to check if the string was null or did only contain whitespace characters.

JSF View

In your XHTML file you probably want to listen to any Ajax event to update your view -- or you figure out the event you need (blur, change, whatever) yourself:

<p:autoComplete ...>
    <p:ajax event="itemSelect" listener="..." update="..." />
    <p:ajax process="@this" update="..." />
</p:autocomplete>

I hope this helps.


An alternative could be something like a "clear" or "reset" button next to the search textfield to make it clear to the user that the value will be cleared.




回答2:


The default autoComplete minQueryLength attribute equals 1 and your search string will be updated when you deleting it until it has lenght of 1 character.

E.g.: You entering 'foo' - and this string is provided to search method (updating after entering first character - minQueryLength = 1)

But when you delete search string - it is also updated until it will have length of 1.

Solution: set attribute minQueryLength="0"

Or:

if you need bigger value add to your autoCompleteMethod(String search) condition:

if (search.length()<={your minQueryLength attribute} )   field = null;



回答3:


Old question, but I think it worths another view.

The problem with minQueryLenth = 0 or minQueryLenth = 1 is that it can return hundreds of options (and for sure the user won't read all of them to choose one). My solution was as follows.

First of all I need the input to be sent to the server as soon as the user select one of its values (in my use case the user is not allowed to go to next step in a wizard if this value is null or empty). So I put an ajax function triggered in the event of a selected value.

xhtml:

<p:autoComplete
    id="someId"
    value="#{myViewScopedBean.selectedValue}"
    ...
    ...
    minQueryLenth="5"
    onblur="autoCompleteLostFocus('someId', 'someCommand()')">

    <p:ajax
        event="itemSelect"
        listener="#{myViewScopedBean.newValueSelected}"
        process="@this"
        update="commandButtonGoToNextStep" />

</p:autoComplete>


<p:remoteCommand
    name="someCommand"
    actionListener="#{myViewScopedBean.setValueNull}"
    update="commandButtonGoToNextStep" />


<p:commandButton
    id="commandButtonGoToNextStep"
    ...
    ...
    disabled="#{myViewScopedBean.selectedValue == null}" />

If the user clean the text, I need to send that value to "myViewScopedBean" and update the component that allows the user to go to the next step. I solved that putting a javascript function that is called when the autocomplete lose focus.

javascript:

function autoCompleteLostFocus(autocompleteId, comand) {

    if ($("[id='" + autocompleteId + "_input']").val().trim() == "") {
        eval(comando);
    }

}

in myViewScopedBean:

public void setValueNull() {
    selectedValue = null;
}

I hope it helps. A lot of work, but the behaviour is exactly what I wanted. The reason for the javascript function is that it just send information to the servlet if the value is equals to "", otherwise it does nothing.




回答4:


From a completely different angle...

Why do you have summaryReportController.device.nickname as a value in autoComplete?

I'd suggest you to use device as a value and specify

  • var
  • itemLabel
  • itemValue
  • converter

in your autocomplete, while your completeMethod will return list of devices filtered by nickname. Converter is implementation of javax.faces.convert.Converter.

See the POJO case in PF Showcase.



来源:https://stackoverflow.com/questions/9877967/reset-value-to-null-in-primefaces-autocomplete-event

工具导航Map