-
1. Re: Update issues with selectOneMenus using selectItems
barbacena Apr 16, 2008 3:55 AM (in response to gimpy21)Post the code. It will help. :P
-
2. Re: Update issues with selectOneMenus using selectItems
gimpy21 Apr 16, 2008 3:53 PM (in response to gimpy21)The bean is long so I'll post it separate.
//imports @Stateful @Name("salesAreaCreator") @Scope(ScopeType.CONVERSATION) @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED) public class SalesAreaCreatorBean implements SalesAreaCreator, Serializable { private static final String UNASSIGNED = "UNALLOCATED"; private List<String> log; @In(required=false) private FacesMessages facesMessages; @In(create=true, required=false) private List<String> states; private List<String> counties; @PersistenceContext private Session session; private String territoryName; private String startRange; private String endRange; private List<String> sourceTerritories; private String selectedRangeSourceTerritory; private List<String> destinationTerritories; private String selectedDestinationTerritory; private String selectedSourceTerritory; private String selectedState; private List<String> selectedCounties; private List<String> selectedStates; private Map<String, Territory> territories; /** * Updates available counties for given state. * * Note: call this for BY COUNTY transfers only. BY STATE transfers do not need this. * @return */ public String selectedStateChanged() { if(selectedState == null) counties.clear(); else updateAvailableCounties(); selectedCounties = new ArrayList<String>(0); return null; } private void updateAvailableCounties() { Query q = //query counties = (List<String>)q.list(); } private void updateLists() { sourceTerritories.clear(); destinationTerritories.clear(); String[] names = territories.keySet().toArray(new String[]{}); Arrays.sort(names); Territory t = null; for(String name : names) { t = territories.get(name); if(t.count() > 0) sourceTerritories.add(name); destinationTerritories.add(name); } //we don't want to have them add items to UNASSIGNED destinationTerritories.remove(UNASSIGNED); //move UNASSIGNED to top of the source list if it's in there int index = sourceTerritories.indexOf(UNASSIGNED); if(index > 0) //it's in there and not at the top { sourceTerritories.remove(index); sourceTerritories.add(0, UNASSIGNED); } } private boolean isValidZipCode(String s) { if(s == null || s.trim().length() != 5) return false; try { Integer.parseInt(s.trim()); return true; } catch(NumberFormatException e) { return false; } } private List<String> getZipCodesInStates(List<String> states) { Query q = //query return (List<String>)q.list(); } private void logRangeTransfer(String source) { } private void logStateTransfer(int zipCount) { } private void logTerritoryTransfer(int zipCount) { } private void logCountyTransfer(int zipCount) { } public String transferByCounties() { if(selectedCounties.size() > 0) { List<String> zips = getZipCodesInCounties(selectedState, selectedCounties); transferZipCodeList(zips, selectedDestinationTerritory); updateLists(); logCountyTransfer(zips.size()); } else { facesMessages.add(FacesMessage.SEVERITY_ERROR, "No counties selected for transfer"); } return null; } private List<String> getZipCodesInCounties(String state, List<String> counties) { Query q = //query return (List<String>)q.list(); } public String transferByTerritories() { if(selectedSourceTerritory != null) { if(selectedDestinationTerritory != null) { if(!selectedSourceTerritory.equals(selectedDestinationTerritory)) { Territory src = territories.get(selectedSourceTerritory); int count = src.count(); src.transferZipCodes(territories.get(selectedDestinationTerritory)); logTerritoryTransfer(count); updateLists(); } else { facesMessages.add(FacesMessage.SEVERITY_ERROR, "Source is also destination"); } } else { facesMessages.add(FacesMessage.SEVERITY_ERROR, "Destination territory not selected"); } } else { facesMessages.add(FacesMessage.SEVERITY_ERROR, "Source territory not selected"); } return null; } public String transferByStates() { if(selectedStates.size() > 0) { List<String> zips = getZipCodesInStates(selectedStates); transferZipCodeList(zips, selectedDestinationTerritory); updateLists(); logStateTransfer(zips.size()); } else { facesMessages.add(FacesMessage.SEVERITY_ERROR, "No states selected for transfer"); } return null; } /** * Pulls all the listed zip codes from everyone and puts them in destination * * @param zipCodes * @param destination */ private void transferZipCodeList(List<String> zipCodes, String destination) { for(Territory t : territories.values()) { if(t.getName().equals(destination)) { t.add(zipCodes); } else { t.remove(zipCodes); } } } /** * selectedRangeSourceTerritory == null will pull from all * @return */ public String transferByRange() { if(selectedDestinationTerritory != null) { if(selectedRangeSourceTerritory == null || !selectedRangeSourceTerritory.equals(selectedDestinationTerritory)) { if( isValidZipCode(startRange) ) { if( isValidZipCode(endRange) ) { int start = Integer.parseInt(startRange); int end = Integer.parseInt(endRange); if(start < end) //a range of zip codes { if(selectedRangeSourceTerritory == null) //a range of many to one transfers { Territory destTer = territories.get(selectedDestinationTerritory); for(Territory curTer : territories.values()) { if(!curTer.getName().equals(selectedDestinationTerritory)) { String curZip = null; Iterator<String> iter = curTer.getCollectionIterator(); while(iter.hasNext()) { curZip = iter.next(); Integer i = Integer.parseInt(curZip); if(start <= i && i <= end) { iter.remove(); destTer.add(curZip); } } } } } else //a range of one to one transfers { Territory from = territories.get(selectedRangeSourceTerritory); Territory to = territories.get(selectedDestinationTerritory); String curZip = null; Iterator<String> iter = from.getCollectionIterator(); while(iter.hasNext()) { curZip = iter.next(); Integer i = Integer.parseInt(curZip); if(start <= i && i <= end) { iter.remove(); to.add(curZip); } } } logRangeTransfer((selectedRangeSourceTerritory == null ? "ALL" : selectedRangeSourceTerritory)); } else if (start == end) //single zip code transfer { for(Territory t : territories.values()) { t.remove(startRange); } territories.get(selectedDestinationTerritory).add(startRange); logRangeTransfer((selectedRangeSourceTerritory == null ? "ALL" : selectedRangeSourceTerritory)); } else { facesMessages.add(FacesMessage.SEVERITY_ERROR, "Start zip code is larger than end zip code"); } } else { facesMessages.add(FacesMessage.SEVERITY_ERROR, "Invalid end zip code"); } } else { facesMessages.add(FacesMessage.SEVERITY_ERROR, "Invalid start zip code"); } setStartRange(null); setEndRange(null); } else { facesMessages.add(FacesMessage.SEVERITY_ERROR, "Source matches destination"); } } else { facesMessages.add(FacesMessage.SEVERITY_ERROR, "No destination selected"); } //TODO: move if called too often updateLists(); return null; } @Destroy @Remove public void destroy() { System.out.println("destroying salesAreaCreator");} public String reset() { log.clear(); counties.clear(); selectedCounties = new ArrayList<String>(); selectedStates = new ArrayList<String>(); territories.clear(); Territory t = new Territory(UNASSIGNED); t.add( getAllZipCodes() ); territories.put(t.getName(), t); updateLists(); return null; } private List<String> getAllZipCodes() { return getZipCodesInStates(states); } @Begin(nested=true) @Create public void initialize() { sourceTerritories = new ArrayList<String>(0); destinationTerritories = new ArrayList<String>(0); counties = new ArrayList<String>(0); territories = new HashMap<String,Territory>(0); log = new ArrayList<String>(0); reset(); } public void setTerritoryName(String name) { this.territoryName = name; } public String getTerritoryName() { return this.territoryName; } public String addTerritory() { if (territoryName != null && territoryName.trim().length() != 0) { Territory t = new Territory(territoryName.trim().toUpperCase()); if (territories.containsKey(t.getName())) { facesMessages.add(FacesMessage.SEVERITY_ERROR, "Territory name already exists"); } else { territories.put(t.getName(), t); updateLists(); log.add("Define sales area " + t.getName()); } } setTerritoryName(null); return null; } /** * Removes the territoryName */ public String removeTerritory() { if(territoryName != null && !territoryName.equals(UNASSIGNED)) // better safe than sorry { Territory toDelete = territories.get(territoryName); toDelete.transferZipCodes( territories.get(UNASSIGNED) ); territories.remove(territoryName); updateLists(); log.add("Remove sales area " + territoryName); } setTerritoryName(null); return null; } public String getStartRange() { return startRange; } public void setStartRange(String startRange) { this.startRange = startRange; } public String getEndRange() { return endRange; } public void setEndRange(String endRange) { this.endRange = endRange; } public String getSelectedRangeSourceTerritory() { return selectedRangeSourceTerritory; } public void setSelectedRangeSourceTerritory(String selectedRangeSourceTerritory) { this.selectedRangeSourceTerritory = selectedRangeSourceTerritory; } public String getSelectedDestinationTerritory() { return selectedDestinationTerritory; } public void setSelectedDestinationTerritory(String selectedDestinationTerritory) { this.selectedDestinationTerritory = selectedDestinationTerritory; } public String getSelectedState() { return selectedState; } public void setSelectedState(String selectedState) { this.selectedState = selectedState; } public List<String> getSelectedCounties() { return selectedCounties; } public void setSelectedCounties(List<String> selectedCounties) { this.selectedCounties = selectedCounties; } public List<String> getStates() { return states; } public List<String> getCounties() { return counties; } public List<String> getSourceTerritories() { return sourceTerritories; } public List<String> getDestinationTerritories() { return destinationTerritories; } public String verify() { String result = "valid"; for(Territory t : territories.values()) { if(t.getName().equals(UNASSIGNED)) { if(t.count() != 0) { facesMessages.add(FacesMessage.SEVERITY_ERROR, "There are unassigned zip codes"); result = null; break; } } else { if(t.count() == 0) { facesMessages.add(FacesMessage.SEVERITY_ERROR, t.getName() + " does not contain zip codes"); result = null; break; } } } return result; } private class Territory { private Collection<String> zipCodes; private String name; public Territory(String name) { this.name = name; zipCodes = new TreeSet<String>(); } public void transferZipCodes(Territory to) { to.add(zipCodes); zipCodes.clear(); } public String getName() { return this.name; } public void add(Collection<String> zipCodes) { this.zipCodes.addAll(zipCodes); } public void remove(Collection<String> zipCodes) { this.zipCodes.removeAll(zipCodes); } public void remove(String zipCode) { this.zipCodes.remove(zipCode); } public void add(String zipCode) { this.zipCodes.add(zipCode); } public int count() { return this.zipCodes.size(); } public Iterator<String> getCollectionIterator() { return this.zipCodes.iterator(); } /** * equality is based on the name only */ public int hashCode() { return name.hashCode(); } public boolean equals(Object o) { if (o == null || !(o instanceof Territory)) return false; return this.hashCode() == o.hashCode(); } //we need this for the list sorting that we do //public int compareTo(Territory other) { return this.name.compareTo(other.name); } } public List<String> getSelectedStates() { return selectedStates; } public void setSelectedStates(List<String> selectedStates) { this.selectedStates = selectedStates; } public List<String> getLog() { return log; } public int getUnassignedCount() { return territories.get(UNASSIGNED).count(); } public String getSelectedSourceTerritory() { return selectedSourceTerritory; } public void setSelectedSourceTerritory(String selectedSourceTerritory) { this.selectedSourceTerritory = selectedSourceTerritory; } }
-
3. Re: Update issues with selectOneMenus using selectItems
gimpy21 Apr 16, 2008 4:01 PM (in response to gimpy21)Now for the page that uses it. The problem can be seen when using the Remove Territory panel.
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:rich="http://richfaces.org/rich" xmlns:a4j="http://richfaces.org/a4j"> <h2>Sales Areas</h2> <a4j:outputPanel ajaxRendered="true"> <a4j:form ajaxSubmit="true"> <a4j:region> <rich:panel id="add_name"> <f:facet name="header">Add Territory</f:facet> <h:panelGrid columns="3"> <h:outputLabel value="Name"/> <h:inputText value="#{salesAreaCreator.territoryName}"/> <a4j:commandButton value="Add" action="#{salesAreaCreator.addTerritory}" reRender="add_name, remove_name, tab_panel, unassigned_count_grid, error_panel" eventsQueue="queue" ignoreDupResponses="true" status="territory_status"/> </h:panelGrid> </rich:panel> </a4j:region> </a4j:form> </a4j:outputPanel> <a4j:outputPanel ajaxRendered="true"> <a4j:form ajaxSubmit="true"> <a4j:region> <rich:panel id="remove_name" rendered="#{not empty salesAreaCreator.destinationTerritories}"> <f:facet name="header">Remove Territory</f:facet> <h:panelGrid columns="3"> <h:outputLabel value="Name"/> <h:selectOneMenu value="#{salesAreaCreator.territoryName}"> <s:selectItems value="#{salesAreaCreator.destinationTerritories}" var="dest" label="#{dest}"/> </h:selectOneMenu> <a4j:commandButton value="Remove" action="#{salesAreaCreator.removeTerritory}" reRender="remove_name, tab_panel, unassigned_count_grid, error_panel" eventsQueue="queue" ignoreDupResponses="true" status="territory_status"/> </h:panelGrid> </rich:panel> </a4j:region> </a4j:form> </a4j:outputPanel> <h:panelGrid id="error_panel"> <h:messages/> </h:panelGrid> <a4j:status forceId="true" id="territory_status" startText="Processing territory..."/> <a4j:status forceId="true" id="transfer_status" startText="Transfering..."/> <a4j:status forceId="true" id="update_status" startText="Updating..."/> <a4j:outputPanel ajaxRendered="true"> <rich:tabPanel id="tab_panel" switchType="ajax" rendered="#{not empty salesAreaCreator.destinationTerritories}"> <rich:tab id="state_tab" label="By State" eventsQueue="queue" ignoreDupResponses="true"> <a4j:form ajaxSubmit="true"> <a4j:region> <rich:panel id="by_state_panel"> <h:selectManyListbox size="5" value="#{salesAreaCreator.selectedStates}"> <s:selectItems value="#{salesAreaCreator.states}" var="state" label="#{state}"/> </h:selectManyListbox> <h:selectOneMenu value="#{salesAreaCreator.selectedDestinationTerritory}"> <s:selectItems value="#{salesAreaCreator.destinationTerritories}" var="dest" label="#{dest}"/> </h:selectOneMenu> <a4j:commandButton value="Transfer" action="#{salesAreaCreator.transferByStates}" reRender="tab_panel, error_panel" eventsQueue="queue" ignoreDupResponses="true" status="transfer_status"/> </rich:panel> </a4j:region> </a4j:form> </rich:tab> <rich:tab id="county_tab" label="By County" eventsQueue="queue" ignoreDupResponses="true"> <a4j:form ajaxSubmit="true"> <h:selectOneMenu value="#{salesAreaCreator.selectedState}"> <s:selectItems value="#{salesAreaCreator.states}" var="state" label="#{state}" hideNoSelectionLabel="true" noSelectionLabel="Select..."/> <a4j:support event="onchange" action="#{salesAreaCreator.selectedStateChanged}" reRender="county_tab, error_panel" ajaxSingle="true" status="update_status" eventsQueue="queue" ignoreDupResponses="true"/> </h:selectOneMenu> <h:selectManyListbox size="5" value="#{salesAreaCreator.selectedCounties}"> <s:selectItems value="#{salesAreaCreator.counties}" var="county" label="#{county}"/> </h:selectManyListbox> <h:selectOneMenu value="#{salesAreaCreator.selectedDestinationTerritory}"> <s:selectItems value="#{salesAreaCreator.destinationTerritories}" var="dest" label="#{dest}"/> </h:selectOneMenu> <a4j:commandButton value="Transfer" action="#{salesAreaCreator.transferByCounties}" reRender="tab_panel, error_panel" eventsQueue="queue" ignoreDupResponses="true" status="transfer_status"/> </a4j:form> </rich:tab> <rich:tab id="territory_tab" label="By Territory" eventsQueue="queue" ignoreDupResponses="true"> <a4j:form ajaxSubmit="true"> <h:selectOneMenu id="territy_source" value="#{salesAreaCreator.selectedSourceTerritory}"> <s:selectItems value="#{salesAreaCreator.sourceTerritories}" var="src" label="#{src}"/> </h:selectOneMenu> <h:selectOneMenu id="territory_destination" value="#{salesAreaCreator.selectedDestinationTerritory}"> <s:selectItems value="#{salesAreaCreator.destinationTerritories}" var="dest" label="#{dest}"/> </h:selectOneMenu> <a4j:commandButton value="Transfer" action="#{salesAreaCreator.transferByTerritories}" reRender="territory_tab, error_panel" eventsQueue="queue" ignoreDupResponses="true" status="transfer_status"/> </a4j:form> </rich:tab> <rich:tab label="By Range" eventsQueue="queue" ignoreDupResponses="true"> <a4j:form ajaxSubmit="true"> <a4j:region> <rich:panel id="range_panel"> <h:outputLabel value="Start"/> <h:inputText value="#{salesAreaCreator.startRange}"/> <h:outputLabel value="End"/> <h:inputText value="#{salesAreaCreator.endRange}"/> <h:selectOneMenu id="range_source" value="#{salesAreaCreator.selectedRangeSourceTerritory}"> <s:selectItems value="#{salesAreaCreator.sourceTerritories}" var="src" label="#{src}" noSelectionLabel="ALL"/> </h:selectOneMenu> <h:selectOneMenu id="range_destination" value="#{salesAreaCreator.selectedDestinationTerritory}"> <s:selectItems value="#{salesAreaCreator.destinationTerritories}" var="dest" label="#{dest}"/> </h:selectOneMenu> <a4j:commandButton value="Transfer" action="#{salesAreaCreator.transferByRange}" reRender="tab_panel, error_panel" eventsQueue="queue" ignoreDupResponses="true" status="transfer_status"/> </rich:panel> </a4j:region> </a4j:form> </rich:tab> </rich:tabPanel> </a4j:outputPanel> <a4j:outputPanel ajaxRendered="true"> <h:panelGrid id="unassigned_count_grid" columns="2" rendered="#{not empty salesAreaCreator.destinationTerritories}"> <h:outputLabel value="Zip codes currenty unassigned:"/> <h:outputLabel value="#{salesAreaCreator.unassignedCount}"/> </h:panelGrid> </a4j:outputPanel> <a4j:outputPanel ajaxRendered="true"> <a4j:form ajaxSubmit="true"> <a4j:region> <rich:panel id="log_panel" rendered="#{not empty salesAreaCreator.log}"> <f:facet name="header">Log</f:facet> <rich:dataList id="log_table" value="#{salesAreaCreator.log}" var="s"> <rich:column> <h:outputText value="#{s}" /> </rich:column> </rich:dataList> </rich:panel> </a4j:region> </a4j:form> </a4j:outputPanel> <a4j:form ajaxSubmit="true"> <a4j:commandButton style="float:right" value="Next" action="#{salesAreaCreator.verify}" reRender="tab_panel, error_panel" immediate="true" eventsQueue="queue" ignoreDupResponses="true" ajaxSingle="true"/> </a4j:form> </ui:composition>
-
4. Re: Update issues with selectOneMenus using selectItems
barbacena Apr 16, 2008 4:29 PM (in response to gimpy21)Your code is so big that I really don't have time to read all.
However, from what I see you didn´t understand the use of <a4j:outputPanel ajaxRendered="true">, because you are still using reRender without limitToList property.
After that, I can see optimizations (the use of regions). My advice is to not optimize until you get it working. Therefore, try to remove queues, regions, and everything that is optimization, until you get it working.
Then read this.
Sorry for not being able to point to the error, but I hope it helps.
p.s.: if you can provide a simples example I would be able to help more. Have a look at: JBSEAM-2864
-
5. Re: Update issues with selectOneMenus using selectItems
gimpy21 Apr 16, 2008 4:49 PM (in response to gimpy21)You're right, I didn't really understand that tag. I'll strip out everything and try again using what the link you provided states. Thanks for the quick reply.
-
6. Re: Update issues with selectOneMenus using selectItems
gimpy21 Apr 16, 2008 6:11 PM (in response to gimpy21)I stripped it down to a simple test case. It looks like I'm missing something fundamental in how JSF and Seam operate together. It removes from the list and returns the list of new values according to the debug prints, but the component is always one delete behind.
test.xhtml:
<!DOCTYPE composition PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:s="http://jboss.com/products/seam/taglib" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:h="http://java.sun.com/jsf/html" xmlns:a4j="http://richfaces.org/a4j"> <a4j:outputPanel layout="none"> <a4j:form> <h:outputLabel value="Select:"/> <h:selectOneMenu value="#{test.selected}" id="menu"> <s:selectItems value="#{test.values}" var="v" label="#{v}"/> </h:selectOneMenu> <a4j:commandButton value="Remove" action="#{test.remove}" reRender="menu"/> </a4j:form> </a4j:outputPanel> <a4j:outputPanel ajaxRendered="true"> <h:messages/> </a4j:outputPanel> <a4j:status startText="Processing..."/> </ui:composition>
testBean:
import javax.ejb.Remove; import javax.ejb.Stateful; import org.jboss.seam.ScopeType; import org.jboss.seam.annotations.Create; import org.jboss.seam.annotations.Destroy; import org.jboss.seam.annotations.Name; import org.jboss.seam.annotations.Scope; @Stateful @Name("test") @Scope(ScopeType.SESSION) public class TestBean implements Test, Serializable { private List<String> values; private String selected; @Create public void initialize() { System.out.println("initializing test bean"); values = new ArrayList<String>(5); values.add("ALPHA"); values.add("BETA"); values.add("FOO"); values.add("BAR"); values.add("NIL"); } @Destroy @Remove public void destroy() {System.out.println("destroying test bean");} public String remove() { System.out.println("removing: " + selected); values.remove(selected); setSelected(null); return null; } public String getSelected() { System.out.println("getSelected: " + selected); return selected; } public void setSelected(String selected) { System.out.println("setSelected from " + this.selected + " to " + selected); this.selected = selected; } public List<String> getValues() { System.out.println("getValues: " + values); return values; } }
-
7. Re: Update issues with selectOneMenus using selectItems
barbacena Apr 16, 2008 6:39 PM (in response to gimpy21)I faced a problem like this, but with @Factory.
Could you try replacing the outputPanel with s:decorate id="menu" and removing the id definition from the selectOneMenu?
-
8. Re: Update issues with selectOneMenus using selectItems
gimpy21 Apr 16, 2008 6:47 PM (in response to gimpy21)It results in the same behavior.
-
9. Re: Update issues with selectOneMenus using selectItems
gimpy21 Apr 18, 2008 6:21 PM (in response to gimpy21)bump
-
10. Re: Update issues with selectOneMenus using selectItems
andygibson.contact.andygibson.net Apr 18, 2008 10:23 PM (in response to gimpy21)Thanks for the shorter code that demonstrates the problem. I took out the ajax stuff from your example, and it appears that the problem remains even without throwing the complexities of AJAX in the mix.
I added a line :
<h:outputText value="Values : #{test.values}"/>
To your page, and every time the list of values displayed there is correct. It seems the problem is with the drop down box lagging and I'm not sure why.
The model is re-bound to the control in the apply values part of the lifecycle before the application is invoked. Once the application is invoked and the item is removed from the list, it seems like this new list is never requsted from the bean by the component.
I combined your logging with my lifecycle phase listener and everything hits at the right times, with the following output :
Initial Page Render
15:57:34,593 DEBUG [LogPhaseListener] Executed Phase RESTORE_VIEW 1 15:57:34,640 INFO [STDOUT] initializing test bean 15:57:34,640 INFO [STDOUT] getSelected: null 15:57:34,640 INFO [STDOUT] getValues: [ALPHA, BETA, FOO, BAR, NIL] 15:57:34,656 INFO [STDOUT] getSelected: null 15:57:34,656 INFO [STDOUT] getValues: [ALPHA, BETA, FOO, BAR, NIL] 15:57:34,656 INFO [STDOUT] getSelected: null 15:57:34,656 INFO [STDOUT] getSelected: null 15:57:34,656 INFO [STDOUT] getSelected: null 15:57:34,656 INFO [STDOUT] getSelected: null 15:57:34,656 INFO [STDOUT] getSelected: null 15:57:34,656 INFO [STDOUT] getSelected: null 15:57:34,656 DEBUG [LogPhaseListener] Execution Time = 63ms 15:57:34,656 DEBUG [LogPhaseListener] Executed Phase RENDER_RESPONSE 6
then I deleted Beta
15:58:12,718 DEBUG [LogPhaseListener] Executed Phase RESTORE_VIEW 1 15:58:12,718 DEBUG [LogPhaseListener] Executed Phase APPLY_REQUEST_VALUES 2 15:58:12,718 INFO [STDOUT] getSelected: null 15:58:12,718 INFO [STDOUT] getValues: [ALPHA, BETA, FOO, BAR, NIL] 15:58:12,734 INFO [STDOUT] getSelected: null 15:58:12,734 DEBUG [LogPhaseListener] Executed Phase PROCESS_VALIDATIONS 3 15:58:12,734 INFO [STDOUT] setSelected from null to BETA 15:58:12,734 DEBUG [LogPhaseListener] Executed Phase UPDATE_MODEL_VALUES 4 15:58:12,734 INFO [STDOUT] removing: BETA 15:58:12,734 INFO [STDOUT] setSelected from BETA to null 15:58:12,734 DEBUG [LogPhaseListener] Executed Phase INVOKE_APPLICATION 5 15:58:12,750 INFO [STDOUT] getSelected: null 15:58:12,750 INFO [STDOUT] getValues: [ALPHA, FOO, BAR, NIL] 15:58:12,750 INFO [STDOUT] getSelected: null 15:58:12,750 INFO [STDOUT] getValues: [ALPHA, FOO, BAR, NIL] 15:58:12,750 INFO [STDOUT] getSelected: null 15:58:12,750 INFO [STDOUT] getSelected: null 15:58:12,765 INFO [STDOUT] getSelected: null 15:58:12,765 INFO [STDOUT] getSelected: null 15:58:12,765 INFO [STDOUT] getSelected: null 15:58:12,765 INFO [STDOUT] getSelected: null 15:58:12,765 DEBUG [LogPhaseListener] Execution Time = 47ms 15:58:12,765 DEBUG [LogPhaseListener] Executed Phase RENDER_RESPONSE 6
This is really weird as it looks like the drop down is taking the values it gets from the apply request values phase and never getting an updated list on the render response phase after the invoke application phase which modified the list.
I added the following code to the remove item method to try and manually put the values in the drop down :
System.out.println("Manually setting values : "+getValues()); binding.getItems().setValue(getValues());
Which gives us :
16:11:44,484 INFO [STDOUT] removing: BAR 16:11:44,484 INFO [STDOUT] setSelected from BAR to null 16:11:44,484 INFO [STDOUT] getValues: [ALPHA, FOO, NIL] 16:11:44,484 INFO [STDOUT] Manually setting values : [ALPHA, FOO, NIL] 16:11:44,484 INFO [STDOUT] getValues: [ALPHA, FOO, NIL] 16:11:44,484 DEBUG [LogPhaseListener] Executed Phase INVOKE_APPLICATION 5 16:11:44,500 INFO [STDOUT] getSelected: null 16:11:44,500 INFO [STDOUT] getSelected: null 16:11:44,500 INFO [STDOUT] getSelected: null 16:11:44,515 INFO [STDOUT] getSelected: null 16:11:44,515 INFO [STDOUT] getSelected: null 16:11:44,515 INFO [STDOUT] getSelected: null 16:11:44,515 INFO [STDOUT] getSelected: null 16:11:44,515 DEBUG [LogPhaseListener] Execution Time = 62ms 16:11:44,515 DEBUG [LogPhaseListener] Executed Phase RENDER_RESPONSE 6
We are removing the item, pushing the list into the drop down, and the control does not ask for the list again, so I have no idea how it is still keeping the value in the drop down until the next time.
This may be a common problem, but I couldn't find an answer by some casual googling. I also tried using an actionListener as well, which gave the same results.
-
11. Re: Update issues with selectOneMenus using selectItems
ben_utzer Jun 14, 2011 8:50 AM (in response to gimpy21)Has there been any news on this issue? I'm facing the same problem now. Any tipps or workarounds?
Regards,
Ben
-
12. Re: Update issues with selectOneMenus using selectItems
gimpy21 Jun 14, 2011 12:54 PM (in response to gimpy21)Hi Ben. I retested this today with Seam 2.2.1.CR1 and I still encounter the same problem. I also looked into the selectOneMenu source and couldn't find anything that stuck out as an immediate culprit. As far as a workaround, I think I used a RichFaces shuttleList.
-
13. Re: Update issues with selectOneMenus using selectItems
alin.heyoulin.qq.com Jun 14, 2011 9:37 PM (in response to gimpy21)This may be a bug of reichfaces3. I test it on richfaces4 and work fine. Use my seam2jsf2
-
14. Re: Update issues with selectOneMenus using selectItems
gimpy21 Jun 15, 2011 10:07 AM (in response to gimpy21)Andy tested with the AJAX components removed, so I don't think it's necessarily RichFaces specific. Does 'seam2jsf2' use JSF 2.x? If so, then I believe we found a useable solution.