panelSeries partialSubmit only works on first row
[Logo]
ICEsoft.org Forums: ICEfaces, ICEmobile, ICEpdf
[Search] Search   [Recent Topics] Recent Topics   [Groups] Home Page | www.icefaces.org  [Register] Register  [Login] Login 
panelSeries partialSubmit only works on first row  XML
Forum Index -> JBoss Seam Integration
Author Message
alexaraujo

Joined: 29/09/2007 00:00:00
Messages: 5
Offline


I am having issues getting a panelSeries to re-render correctly after a partialSubmit on any row besides the first row. The behavior I'm noticing is that a change to a row besides row one results in row one being replaced by the row whose update triggered the re-render. The other oddity is that the change is applied to both rows, but only row one is re-rendered correctly.

A more concrete explanation of this - if there are two rows in the panelSeries and I check a checkbox in row two that is supposed render other elements in row two, row one is replaced with row two and the elements that should have been rendered in row two are only rendered in row one.

Does anyone have suggestions on how to fix this or find the cause of this strangeness?

I am using ICEfaces 1.8.1, Seam 2.2.0, and Glassfish 2.1. Relevant code snippet below (apologies if it does not render correctly). Thanks.

Code:
 <ice:panelSeries var="key" varStatus="status" value="#{newAffiliateKey.keyInfoList}">
 
 	<fieldset class="unsub-form" id="manual-add-form">
 		<ul>
 			<li class="multiline">
 				<span class="manual-key-label" style="width: 198px;"><ice:outputText value="#{messages['adv.newAffiliateKey.li.span.affiliateName']}"/></span>
 				<span class="manual-key-label" style="width: 198px;"><ice:outputText value="#{messages['adv.newAffiliateKey.li.span.emailAddress']}"/></span>
 				<span class="manual-key-label" style="width: 80px;"><ice:outputText value="#{messages['adv.newAffiliateKey.li.span.listSize']}"/></span>
 				<span class="manual-key-label" style="width: 198px;"><ice:outputText value="#{messages['adv.newAffiliateKey.li.span.keyCustomization']}"/></span>
 				<!-- Add/Remove Rows -->
 				<ice:commandLink rendered="#{newAffiliateKey.keyInfoList.size() > 1}" action="#{newAffiliateKey.removeManualKey(key)}" title="delete">
 					<ice:graphicImage url="/resources/adv/images/delete.png" alt="delete" width="16" height="16"/>
 				</ice:commandLink>
 				<ice:commandLink rendered="#{newAffiliateKey.keyInfoList.size() == 1 || key.index == newAffiliateKey.keyInfoList.size() - 1}" styleClass="add-line" id="first-line-add" action="#{newAffiliateKey.addManualKey}">
 					<ice:graphicImage url="/resources/adv/images/add.png" alt="add" width="16" height="16"/>
 				</ice:commandLink>
 			</li>
 			<li class="multiline">
 				<<s:decorate template="../layout/edit.xhtml">
 					<ui:param name="hideLabel" value="#{true}"/>
 					<ice:inputText styleClass="aff-name-input text"
 									 value="#{key.affiliateName}"/>
 					<ice:inputText styleClass="email-addr-input text"
 									 value="#{key.cleanAddress}"/>
 					<ice:inputText styleClass="list-size-input text"
 									 value="#{key.listSize}"/>
 					<s:span rendered="#{currentSite.site.allowDownloadCustomizations}">
 						<ice:selectBooleanCheckbox id="download" title="#{status.index}" valueChangeListener="#{newAffiliateKey.valueChanged}" value="#{newAffiliateKey.getKeyInfo(status.index).download}" partialSubmit="true"/>
 						<ice:outputText value="#{messages['adv.newAffiliateKey.download']}"/>
 						<ice:selectBooleanCheckbox id="upload" title="#{status.index}" valueChangeListener="#{newAffiliateKey.valueChanged}" value="#{key.upload}" partialSubmit="true"/>
 						<ice:outputText value="#{messages['adv.newAffiliateKey.upload']}"/>
 					</s:span>
 					<s:span rendered="#{currentSite.site.allowPurgeDownloads}">
 						<ice:selectBooleanCheckbox value="#{key.downloadScrub}"/>
 						<ice:outputText value="#{messages['adv.newAffiliateKey.downloadCustomizations.scrub']}"/>
 					</s:span>
 					<ice:selectBooleanCheckbox id="expiration" title="#{status.index}" valueChangeListener="#{newAffiliateKey.valueChanged}" value="#{key.expiration}" partialSubmit="true"/>
 					<ice:outputText value="#{messages['adv.newAffiliateKey.expiration']}"/>
 					<ice:selectBooleanCheckbox value="#{key.autoRenew}"/>
 					<ice:outputText value="#{messages['adv.newAffiliateKey.uploadOptions.autoRenew']}"/>
 				</s:decorate>
 			</li>
 			<li class="multiline">
 				<s:span rendered="#{newAffiliateKey.availableDomains.size() gt 1}" styleClass="manual-key-label" style="width: 198px;"><ice:outputText value="Unsubscribe Domain"/></s:span>
 				<s:span rendered="#{key.download}" styleClass="manual-key-label" style="width: 198px;">
 					<ice:outputText value="Download Options"/>
 				</s:span>
 				<s:span rendered="#{key.expiration}" styleClass="manual-key-label" style="width: 198px;">
 					<ice:outputText value="Expiration Date"/>
 				</s:span>
 			</li>
 			<li class="multiline">
 				<s:decorate template="../layout/edit.xhtml">
 					<s:span rendered="#{newAffiliateKey.availableDomains.size() gt 1}">
 						<ice:selectOneMenu value="#{key.domainID}">
 							<f:selectItems value="#{newAffiliateKey.availableDomains}"/>
 						</ice:selectOneMenu>
 					</s:span>
 					<ice:outputText style="display: inline;  padding-right: 72px" rendered="#{key.download}">
 						<ice:selectBooleanCheckbox value="#{key.downloadText}"/>
 						<ice:outputText>#{messages['adv.newAffiliateKey.downloadCustomizations.text']}</ice:outputText>
 
 						<ice:selectBooleanCheckbox value="#{key.downloadHash}"/>
 						<ice:outputText>#{messages['adv.newAffiliateKey.downloadCustomizations.hash']}</ice:outputText>
 
 						<ice:selectBooleanCheckbox value="#{key.downloadDelta}"/>
 						<ice:outputText>#{messages['adv.newAffiliateKey.downloadCustomizations.delta']}</ice:outputText>
 					</ice:outputText>
 					<s:span rendered="#{key.expiration}">
 						<ice:selectInputDate style="display: inline; width: 187px;" renderAsPopup="true" renderMonthAsDropdown="true" renderYearAsDropdown="true" popupDateFormat="MM/dd/yyyy"
 							imageDir="/resources/adv/images/" value="#{key.expireDate}"/>
 					</s:span>
 				</s:decorate>
 			</li>
 			<s:span rendered="#{key.upload}">
 				<li class="multiline">
 					<s:decorate template="../layout/edit.xhtml">
 						<span class="manual-key-label" style="width: 496px;"><ice:outputText>#{messages['adv.newAffiliateKey.uploadOptions']}</ice:outputText></span>
 						<s:span rendered="#{key.uploadOption eq 'CUSTOM'}"><ice:outputText>Custom Message</ice:outputText></s:span>
 					</s:decorate>
 				</li>
 				<li>
 					<s:decorate template="../layout/edit.xhtml">
 						<ice:panelGrid columns="2" styleClass="new-aff-keys-padding">
 							<ice:panelGroup>
 								<ice:selectOneRadio id="uploadOption" title="#{status.index}" valueChangeListener="#{newAffiliateKey.valueChanged}" partialSubmit="true" styleClass="aff-keys-upload-options radio" value="#{key.uploadOption}" layout="pageDirection">
 									<f:selectItem itemValue="ALL" itemLabel="#{messages['adv.settings.general.affiliateUploadSettings.all']}"/>
 									<f:selectItem itemValue="UNSUB_ONLY" itemLabel="#{messages['adv.settings.general.affiliateUploadSettings.unsubOnly']}"/>
 									<f:selectItem itemValue="NO_UNSUB_PAGE" itemLabel="#{messages['adv.settings.general.affiliateUploadSettings.noUnsubPage']}"/>
 									<f:selectItem itemValue="CUSTOM" itemLabel="#{messages['adv.settings.general.affiliateUploadSettings.custom']}"/>
 								</ice:selectOneRadio>
 							</ice:panelGroup>
 							<ice:panelGroup rendered="#{key.uploadOption eq 'CUSTOM'}">
 								<ice:inputTextarea styleClass="aff-key-custom-message" id="Name" value="#{sitesHome.instance.customUnsubMessage}" rows="5" cols="65"/>
 							</ice:panelGroup>
 						</ice:panelGrid>
 					</s:decorate>
 
 				</li>
 			</s:span>
 
 		</ul>
 	</fieldset>
 
 	</ice:panelSeries>
 
alexaraujo

Joined: 29/09/2007 00:00:00
Messages: 5
Offline


To further add to my confusion, I have turned on debugDOMUpdate and the update is for the correct row. It appears that the issue is the DOM update not being applied to the correct row once the browser receives the update.

Has anyone ran into something similar? I would think that I have to be doing something obviously wrong otherwise lots of people would have seen this issue.

Thanks.
judy.guglielmin

Joined: 20/02/2007 00:00:00
Messages: 1196
Offline


Are you creating your datatable (within the panel series) with an @Factory notation? Perhaps the datatable is not being updated? Hard to tell without looking in depth at beans, etc (not that we have time to do so right now), but you might want to check your values in the list before the render and afterwards to help track it down.
alexaraujo

Joined: 29/09/2007 00:00:00
Messages: 5
Offline


Hi Judy, I am using a page action to load an empty row into the panelSeries list initially (Code:
<action execute="#{newAffiliateKey.loadData}" on-postback="false"/>
), and a user can add additional empty rows by using a (+) icon on the first and subsequent rows. The backing bean is page scoped.

The template snippet above is the entire panelSeries. Below is the relevant backing bean code. Thank you for taking a look.

Code:
 @Name("newAffiliateKey")
 @Scope(ScopeType.PAGE)
 public class NewAffiliateKeyAction implements NewAffiliateKey, Serializable {
   public void loadData() {
 		site = sitesHome.getInstance();
 		keyInfoList.add(new KeyInfo(site.isAllowTextDownloads(), site.isAllowHashDownloads(), site.isAllowPurgeDownloads(),
 				site.isAllowDeltaDownloads(), site.getAffiliateUploadOptions(), site.getCustomUnsubMessage()));
   }
 
   public void addManualKey() {
 		KeyInfo key = new KeyInfo(site.isAllowTextDownloads(), site.isAllowHashDownloads(), site.isAllowPurgeDownloads(),
 				site.isAllowDeltaDownloads(), site.getAffiliateUploadOptions(), site.getCustomUnsubMessage());
 		key.setIndex(keyInfoList.size());
 		keyInfoList.add(key);
 	}
 
 	public void removeManualKey(KeyInfo removeMe) {
 		keyInfoList.remove(removeMe.getIndex());
 		for (KeyInfo key : keyInfoList) {
 			if (key.getIndex() > removeMe.getIndex()) {
 				key.setIndex(key.getIndex() - 1);
 			}
 		}
   }
 }
 
judy.guglielmin

Joined: 20/02/2007 00:00:00
Messages: 1196
Offline


Personally, I would not use page-scoped.....the problem probably lies in your handling of the entities and the list/datamodel you are using for your rowselector. Usually, the rowselector is used to obtain the details screen, the data updated and then the list reshown, correct? I have found that a stateless list in a conversation-scoped bean for the list to be used is easiest. You will have to find what works best with your design though. I think I actually did this in the open18ice application that is found with Dan Allens' Seam In Action code examples. (just with a datatable vs panelSeries, but both use datamodel for var).
alexaraujo

Joined: 29/09/2007 00:00:00
Messages: 5
Offline


Thanks Judy. The list items are actually just empty dynamic form elements that are pre-populated with default values and passed to a @Stateless service type component when the user submits the form, so there are no actual entities that are managed in the list. It seemed like page scoping was a good fit for this type of list, but at this point I just want to get it to work :).

The issue may be that I am not using a rowSelector. I am simply binding the form elements directly to properties in the list elements and setting partialSubmit="true" on the ones that toggle other UI form inputs to appear in the corresponding row. I will experiment with switching things over to a rowSelector; perhaps conversation scoping things as you suggested.

I have also downloaded the open18ice code samples for reference. Do you happen to remember if this particular example is in the "projects-ch12" or "projects-part1" directory?

Thanks again.
judy.guglielmin

Joined: 20/02/2007 00:00:00
Messages: 1196
Offline


It's just in the protoypes/projects part of the open18 example code. (no chapters in particular AFAIK as it relates to many of the chapters all at one go).

Sorry, I misread your posting and thought you were using rowselector for selecting a particular item from the list. you should still be able to check the datamodel backing the var in the panelSeries to determine if the value(s) in the list is correct. Now that I reread this, this might simple be a case of using the <ice:setEventPhase> component (ensuring that your change gets placed in the model during the current jsf lifecycle). Might be worth a try before you go changing anything.
alexaraujo

Joined: 29/09/2007 00:00:00
Messages: 5
Offline


Hi Judy, I looked at the scorecard list example in the open18ice code and it looks like it is slightly different than what I am trying to do. The datatable in the example does not actually enclose the commandbutton that triggers the display of the Add a New Round section. It also looks like the rowselectionlistener for the page is commented out in myScoreCard.page.xml.

I have examined the datamodel before/after rendering and it appears to have the correct values applied from the form. I also stepped through the CheckboxRenderer.encodeBegin() method and verified that the correct DOM is being generated. Furthermore, I examined the DOM changes that were pushed to the browser in the response and they look correct there as well (i.e., the updates were for the correct row:clientId).

Is this potentially a JavaScript issue? If so, do you have any suggestions on how to debug the DOM manipulation that is occurring or a way to override it with my own?

Thanks.
judy.guglielmin

Joined: 20/02/2007 00:00:00
Messages: 1196
Offline


Did you also look at the <ice:setEventPhase> component? What you want is for the datamodel to be correct during the invoke application as well as the render response phase, correct? Is is possible that you are checking it during the update model phase and it's Ok there but not in phases 5 & 6?
Check out the example for this component (either component-showcase or seam-comp-showcase) and see how it behaves enabled and disabled to see if this looks familiar.
 
Forum Index -> JBoss Seam Integration
Go to:   
Powered by JForum 2.1.7ice © JForum Team