<p:autocomplete> fails for me if I set the required attribute = true. It seems that public void broadcast(javax.faces.event.FacesEvent event) .... is not called when this attribute is set to true and consequently, protected void encodeSuggestionsAsTable(FacesContext context, AutoComplete ac, List items, Converter converter) receives a null for the items list. If I change nothing but remove required="true" from the <p:autocomplete> tag, all works well.
Thanks,
Autocomplete fails with required="true"
- undermensch
- Posts: 140
- Joined: 08 Jul 2010, 14:37
- Location: Florida, United States
PrimeFaces-11.0.6 / Wildfly 24
- undermensch
- Posts: 140
- Joined: 08 Jul 2010, 14:37
- Location: Florida, United States
A little elaboration:
When required is set to true in the <p:autocomplete> tag, validation fails when super.validate(context) is called in overridden validate method in autocomplete. As a consequence broadcast(javax.faces.event.FacesEvent event) is not called and encodeSuggestionsAsTable(FacesContext context, AutoComplete ac, List items, Converter converter) receives a null for the items list. Could the validate method of autocomplete be altered to only call super.validate(context) on itemSelect event? With the following change, autocomplete now works for me with attribute required set to true.
Thanks
When required is set to true in the <p:autocomplete> tag, validation fails when super.validate(context) is called in overridden validate method in autocomplete. As a consequence broadcast(javax.faces.event.FacesEvent event) is not called and encodeSuggestionsAsTable(FacesContext context, AutoComplete ac, List items, Converter converter) receives a null for the items list. Could the validate method of autocomplete be altered to only call super.validate(context) on itemSelect event? With the following change, autocomplete now works for me with attribute required set to true.
Code: Select all
@Override
public void validate(FacesContext context) {
++ if (!customEvents.isEmpty()) {
super.validate(context);
if (isValid()) {
for (Iterator<String> customEventIter = customEvents.keySet().iterator(); customEventIter.hasNext();) {
AjaxBehaviorEvent behaviorEvent = customEvents.get(customEventIter.next());
SelectEvent selectEvent = new SelectEvent(this, behaviorEvent.getBehavior(), getValue());
if (behaviorEvent.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES)) {
selectEvent.setPhaseId(PhaseId.PROCESS_VALIDATIONS);
}
super.queueEvent(selectEvent);
}
}
++ }
}
Thanks
PrimeFaces-11.0.6 / Wildfly 24
What is about an issue ticket?
PrimeFaces Cookbook (2. edition): http://ova2.github.io/primefaces-cookbook/ Learning Angular UI Development with PrimeNG: https://github.com/ova2/angular-develop ... th-primeng Blog: https://medium.com/@OlegVaraksin
PrimeFaces 3.0.M2 / 3.0.M3-SNAPSHOT, Spring Web Flow 2.3.0.RELEASE, Mojarra 2.0.4-b09, Jetty 6, Tomcat 6
- undermensch
- Posts: 140
- Joined: 08 Jul 2010, 14:37
- Location: Florida, United States
Thanks for creating the issue ticket. The quick patch I posted does create a problem if you are submitting the autocomplete value via event from another control & value has not been set already via ajax by autocomplete. I posted a revised patch that avoids this problem on another post that deals with converter being called multiple times (before itemSelect event). viewtopic.php?f=3&t=14464&p=43754#p43754. I also include the revision below; of course, this issue will, I hope, be resolved more elegantly, by the Primefaces team (now that you have created a ticket).
Code: Select all
...
public void setPanelStyleClass(java.lang.String _panelStyleClass) {
getStateHelper().put(PropertyKeys.panelStyleClass, _panelStyleClass);
handleAttribute("panelStyleClass", _panelStyleClass);
}
private static final Collection<String> EVENT_NAMES = Collections.unmodifiableCollection(Arrays.asList("blur", "change", "valueChange", "click", "dblclick", "focus", "keydown", "keypress", "keyup", "mousedown", "mousemove", "mouseout", "mouseover", "mouseup", "select", "itemSelect"));
private Map<String, AjaxBehaviorEvent> customEvents = new HashMap<String, AjaxBehaviorEvent>();
++ private boolean endemic = false;//flag to indicate if validation has been triggered internally, so that form submission,etc will call validation, converter, setter
public final static String STYLE_CLASS = "ui-autocomplete";
public final static String INPUT_CLASS = "ui-autocomplete-input ui-inputfield ui-widget ui-state-default ui-corner-all";
public final static String INPUT_WITH_DROPDOWN_CLASS = "ui-autocomplete-input ui-inputfield ui-widget ui-state-default ui-corner-left";
public final static String DROPDOWN_ICON_CLASS = "ui-autocomplete-dropdown ui-state-default ui-corner-right";
public final static String PANEL_CLASS = "ui-autocomplete-panel ui-widget-content ui-corner-all ui-helper-hidden";
public final static String LIST_CLASS = "ui-autocomplete-items ui-autocomplete-list ui-widget-content ui-widget ui-corner-all ui-helper-reset";
public final static String TABLE_CLASS = "ui-autocomplete-items ui-autocomplete-table ui-widget-content ui-widget ui-corner-all ui-helper-reset";
public final static String ITEM_CLASS = "ui-autocomplete-item ui-autocomplete-list-item ui-corner-all";
public final static String ROW_CLASS = "ui-autocomplete-item ui-autocomplete-row ui-widget-content";
@Override
public Collection<String> getEventNames() {
return EVENT_NAMES;
}
@Override
public void queueEvent(FacesEvent event) {
FacesContext context = FacesContext.getCurrentInstance();
String eventName = context.getExternalContext().getRequestParameterMap().get(Constants.PARTIAL_BEHAVIOR_EVENT_PARAM);
++ endemic=true;//this is an autocomplete event
if (eventName != null && eventName.equals("itemSelect") && event instanceof AjaxBehaviorEvent) {
customEvents.put("itemSelect", (AjaxBehaviorEvent) event);
} else {
super.queueEvent(event);
}
}
private List suggestions = null;
@Override
public void broadcast(javax.faces.event.FacesEvent event) throws javax.faces.event.AbortProcessingException {
super.broadcast(event);
FacesContext facesContext = FacesContext.getCurrentInstance();
MethodExpression me = getCompleteMethod();
if (me != null && event instanceof org.primefaces.event.AutoCompleteEvent) {
suggestions = (List) me.invoke(facesContext.getELContext(), new Object[]{((org.primefaces.event.AutoCompleteEvent) event).getQuery()});
if (suggestions == null) {
suggestions = new ArrayList();
}
}
}
@Override
public void validate(FacesContext context) {
++ if (!customEvents.isEmpty()||!endemic) {//check to see if itemSelect has been added to customEvents map or if validation not triggered by autocomplete event
super.validate(context);
if (isValid()) {
for (Iterator<String> customEventIter = customEvents.keySet().iterator(); customEventIter.hasNext();) {
AjaxBehaviorEvent behaviorEvent = customEvents.get(customEventIter.next());
SelectEvent selectEvent = new SelectEvent(this, behaviorEvent.getBehavior(), getValue());
if (behaviorEvent.getPhaseId().equals(PhaseId.APPLY_REQUEST_VALUES)) {
selectEvent.setPhaseId(PhaseId.PROCESS_VALIDATIONS);
}
super.queueEvent(selectEvent);
}
}
++ }
++ endemic=false;//reset flag
}
...
PrimeFaces-11.0.6 / Wildfly 24
-
- Prime
- Posts: 18616
- Joined: 05 Jan 2009, 00:21
- Location: Cybertron
- Contact:
Fixed by jumping to render response after calling completeMethod. Your patch was complicated to fix this simple problem.
- undermensch
- Posts: 140
- Joined: 08 Jul 2010, 14:37
- Location: Florida, United States
Great! I knew your fix would handle it better than my patch. Thank you!
PrimeFaces-11.0.6 / Wildfly 24
-
- Prime
- Posts: 18616
- Joined: 05 Jan 2009, 00:21
- Location: Cybertron
- Contact:
Thanks for all the feedback!
-
- Information
-
Who is online
Users browsing this forum: No registered users and 22 guests