Probleme mit AJAX und dynamischen Formularen (Seam)

brunce

Grünschnabel
Hallo,

in meiner Seam-Applikation funktionieren die Formulare nicht richtig:
Ich habe auf einer Seite eine Auswahl nach der ich dynamisch ein Formulare anzeigen lasse. Die Formulare zeigen die Daten richtig an, allerdings funktionieren keine Links. Die Methoden in der Bean werden nicht aufgerufen.
Nachdem ich einmal den Submit-button des Formulars geklickt habe, funktionieren die Links wieder.

Aber auch nur solange bis ich ein anderes Formular ausgewählt habe.
Der Klick auf den Submit-Button macht beim ersten mal auch keinen Methodenaufruf, beim zweiten mal ist dann alles korrekt.

Das gleiche Problem tritt auch bei einer anderen Seite auf. Der Aufbau mit dem dynamischen Formular ist ähnlich. Siehe ein vorheriger Thread von mir. Hier tritt genau das gleiche Problem auf, wenn ich in der SelectBox eine andere Tabelle wähle und der Inhalt neu geladen wird.

Woran kann das liegen?

Ich habe noch nicht so viel Erfahrung mit den unterschiedlichen Komponenten, vielleicht liegt da der Fehler.
Nachfolgend der Quelltext. Getter und Setter und irrelevante Methoden habe ich mal weggelassen. Kritik ist durchaus erwünscht.

SelectMachine.java
Code:
@Name("selectMachine")
@Stateful
@Scope(ScopeType.SESSION)
public class SelectMachine implements SelectMachineLocal {

	@Logger private Log log;
	
	@In MachineGroupDao machineGroupDao;
	@In MachineTypeDao machineTypeDao;
	@In MachineDao machineDao;
	
	private String searchTokenGroup;
	private String searchTokenType;
	private String searchTokenMachine;
	
	private MachineGroupEntity selectedGroup;
	private MachineTypeEntity selectedType;
	private MachineEntity selectedMachine;

	@Create
	public void init() {
		log.info("selectMachine {0}", "init() ");
		selectedGroup = null;
		selectedType = null;
		selectedMachine = null;
	}
	
	public List<MachineGroupEntity> autoCompleteGroup(Object event) {
		log.info("selectMachine {0}", "autoCompleteGroup() " + event);		
		
		List<MachineGroupEntity> queryResult = new ArrayList<MachineGroupEntity>();
		
		String pref = event.toString();
	    try{
	    	queryResult = machineGroupDao.getByNameSuggestion(pref);	    	
	    } catch (Exception e) {
        	e.printStackTrace();
	    }
	    
	    return queryResult;
	}
	
	public List<MachineTypeEntity> autoCompleteType(Object event) {		
		log.info("selectMachine {0}", "autoCompleteType() " + event);
		
		noticeChange();
		
		List<MachineTypeEntity> queryResult = new ArrayList<MachineTypeEntity>();
	    
		String pref = event.toString();
	    try{
	    	queryResult = machineTypeDao.getByNameAndGroupSuggestion(pref, selectedGroup);	    	
	    } catch (Exception e) {
        	e.printStackTrace();
	    }
	    
	    return queryResult;		
	}
	
	public List<MachineEntity> autoCompleteMachine(Object event) {		
		log.info("selectMachine {0}", "autoCompleteMachine() " + event.toString());
		
		noticeChange();
		
		List<MachineEntity> queryResult = new ArrayList<MachineEntity>();
	    
		String pref = event.toString();
	    try{
	    	queryResult = machineDao.getByNumberAndTypeAndGroupSuggestion(pref, selectedType, selectedGroup);	    	
	    } catch (Exception e) {
        	e.printStackTrace();
	    }
	    
	    return queryResult;		
	}
	
	public String saveChanges() {		
		log.info("selectMachine {0}", "saveChanges() " + selectedMachine);
		machineDao.update(selectedMachine);
		
		return "";
	}
	
	/**
	 * @return the searchTokenGroup
	 */
	public String getSearchTokenGroup() {
		return searchTokenGroup;
	}

	/**
	 * @param searchTokenGroup the searchTokenGroup to set
	 */
	public void setSearchTokenGroup(String searchTokenGroup) {
		log.info("selectMachine {0}", "setSearchTokenGroup() " + searchTokenGroup);
		searchTokenGroup = searchTokenGroup.trim();
		List<MachineGroupEntity> groups =  machineGroupDao.getByName(searchTokenGroup);
		if(groups.size() > 0) {
			setSelectedGroup(groups.get(0));
		} else {
			setSelectedGroup(null);
		}
		this.searchTokenGroup = searchTokenGroup;
	}


	/**
	 * @return the searchTokenType
	 */
	public String getSearchTokenType() {
		return searchTokenType;
	}

	/**
	 * @param searchTokenType the searchTokenType to set
	 */
	public void setSearchTokenType(String searchTokenType) {
		log.info("selectMachine {0}", "setSearchTokenType() " + searchTokenType);
		searchTokenType = searchTokenType.trim();
		List<MachineTypeEntity> types =  machineTypeDao.getByNameAndGroup(searchTokenType, selectedGroup);
		if(types.size() > 0) {
			setSelectedType(types.get(0));
		} else {
			setSelectedType(null);
		}
		this.searchTokenType = searchTokenType;
	}

	/**
	 * @return the searchTokenMachine
	 */
	public String getSearchTokenMachine() {
		return searchTokenMachine;
	}

	/**
	 * @param searchTokenMachine the searchTokenMachine to set
	 */
	public void setSearchTokenMachine(String searchTokenMachine) {
		log.info("selectMachine {0}", "setSearchTokenMachine() " + searchTokenMachine);
		searchTokenMachine = searchTokenMachine.trim();
		List<MachineEntity> machines =  machineDao.getByNumberAndTypeAndGroup(searchTokenMachine, selectedType, selectedGroup);
		if(machines.size() > 0) {
			setSelectedMachine(machines.get(0));
		} else {
			setSelectedMachine(null);
		}
		this.searchTokenMachine = searchTokenMachine;
	}

	/**
	 * Die Methode soll helfen Änderungen korrekt in der Bean zu übertragen. 
	 */
	public void noticeChange() {		
		log.info("selectMachine {0}", "noticeChange() " + selectedGroup + " || " + selectedType + " || " + selectedMachine);		
	}

	@Destroy @Remove @End
	public void destroy() {
	}
}

editMachineData.xhtml wählt die zu verändernde Maschine aus und included editMachine.xhtml.
HTML:
<a:form id="selectMachineToChange">
		<h3>Maschine wählen</h3>
		
		<h:panelGrid columns="4" styleClass="formLayoutHorizontal">
			<h:panelGrid columns="1" styleClass="formTable" rowClasses="formTableRowLabel, formTableRowInput">				
				<h:outputText value="Maschinengruppe" />		
				<h:panelGroup>
			
					<h:inputText value="#{selectMachine.searchTokenGroup}" id="groupSearch" onclick="#{r:component('groupSuggestion')}.callSuggestion(true)">				
						<a:support ajaxSingle="true" 
								event="onblur"
								actionListener="#{selectMachine.noticeChange}"/>				
					</h:inputText>
					<r:suggestionbox for="groupSearch" id="groupSuggestion" 
							suggestionAction="#{selectMachine.autoCompleteGroup}" 
							nothingLabel="#{messages.misc_NoEntryAvaiable}"
							var="suggest" fetchValue="#{suggest.name}" 
							value="#{selectMachine.searchTokenGroup}">						
						<r:column>
							<h:outputText value="#{suggest.name}" />
						</r:column>
					</r:suggestionbox>

				</h:panelGroup>
			</h:panelGrid>
				
			<h:panelGrid columns="1" styleClass="formTable" rowClasses="formTableRowLabel, formTableRowInput">
				<h:outputText value="Maschinentyp" />
				<h:panelGroup>
				
					<h:inputText value="#{selectMachine.searchTokenType}" id="typeSearch" onclick="#{r:component('typeSuggestion')}.callSuggestion(true)">
						<a:support ajaxSingle="true" 
								event="onblur" 
								actionListener="#{selectMachine.noticeChange}" />
					</h:inputText>
					<r:suggestionbox for="typeSearch" id="typeSuggestion" 
							suggestionAction="#{selectMachine.autoCompleteType}" 
							nothingLabel="#{messages.misc_NoEntryAvaiable}"
							var="suggest" fetchValue="#{suggest.name}">						
						<r:column>
							<h:outputText value="#{suggest.name}" />
						</r:column>
					</r:suggestionbox>
					
				</h:panelGroup>
			</h:panelGrid>
			
			<h:panelGrid columns="1" styleClass="formTable" rowClasses="formTableRowLabel, formTableRowInput">
				<h:outputText value="Maschine" />
				<h:panelGroup>
				
					<h:inputText value="#{selectMachine.searchTokenMachine}" id="machineSearch" onclick="#{r:component('machineSuggestion')}.callSuggestion(true)">					
			<ui:remove>Remove weil beim verlassen des feldes unnötig
						<a:support ajaxSingle="true" 
								event="onblur"
								actionListener="#{selectMachine.noticeChange}" 
								reRender="editMachinePanel" />
			</ui:remove>																
					</h:inputText>
					<r:suggestionbox for="machineSearch" id="machineSuggestion" 
							suggestionAction="#{selectMachine.autoCompleteMachine}" 
							var="suggest" fetchValue="#{suggest.number}" 
							nothingLabel="#{messages.misc_NoEntryAvaiable}"
							value="#{selectMachine.searchTokenMachine}">						
						<r:column>
							<h:outputText value="#{suggest.number}" />
						</r:column>
						<a:support event="onselect"
								actionListener="#{selectMachine.noticeChange}" 
								reRender="editMachinePanel" />
					</r:suggestionbox>					
				</h:panelGroup>
			</h:panelGrid>
		</h:panelGrid>	
			
		<br /><hr />
		
		<a:outputPanel id="editMachinePanel" >
			<h3>Maschine bearbeiten</h3>
			<a:status>
				<f:facet name="start">
					<img src="../images/loading.gif" />
	            </f:facet>
	            <f:facet name="stop">
	            	<ui:include src="components/editMachine.xhtml">
   						<ui:param name="machine" value="#{selectMachine.selectedMachine}" />   				
   					</ui:include>		            
	        	</f:facet>
			</a:status>
		</a:outputPanel>
		<a:outputPanel ajaxRendered="true">
			<r:messages />
		</a:outputPanel>		
	</a:form>

editMachine.xhtml für das Bearbeiten einer Maschine. Änderungen werden nur übernommen nachdem einmal der submit-Button bestätigt wurde.
HTML:
<ui:composition 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:c="http://java.sun.com/jstl/core"
	xmlns:a="http://richfaces.org/a4j"
	xmlns:r="http://richfaces.org/rich"
	xmlns:s="http://jboss.com/products/seam/taglib" contentType="text/html">
		
	<c:choose>
		<c:when test="#{empty machine}">					
			Keine Maschine ausgewählt.<br />
		</c:when>
		<c:otherwise>
			<h:form id="selectDataToChange">
				[Standort ändern] | [Kunde ändern]
				<h:panelGrid columns="3" styleClass="formLayoutHorizontal">
					<h:panelGrid columns="1" styleClass="formTable" rowClasses="formTableRowLabel, formTableRowInput">				
						<h:outputText value="Maschinennummer" />		
						<h:inputText value="#{machine.number}" />
						<h:outputText value="Kommissionsnummer" />		
						<h:inputText value="#{machine.commissionNo}" />
						<h:outputText value="Stücklistennummer" />
						<h:inputText value="#{machine.partsList}" />
						
						<h:outputText value="Maschinentyp" />
						<h:selectOneMenu value="#{machine.type}" styleClass="formInputText">
							<s:selectItems value="#{machineTypeDao.allActive}" var="machinetype" label="#{machinetype.name}" noSelectionLabel="" />
							<s:convertEntity />
						</h:selectOneMenu>
						
						<h:outputText value="Steuerungstyp" />
						<h:selectOneMenu value="#{machine.controlType}" styleClass="formInputText">
							<s:selectItems value="#{controlTypeDao.allActive}" var="controltype" label="#{controltype.name}" noSelectionLabel="" />
							<s:convertEntity />
						</h:selectOneMenu>
				
					</h:panelGrid>
					<h:panelGrid columns="1" styleClass="formTable" rowClasses="formTableRowLabel, formTableRowInput">				
						<h:outputText value="Reaktionszeit" />		
						<h:inputText value="#{machine.reactionTime}" />
						<h:outputText value="Gewährleistungsbeginn" />		
						<h:inputText value="#{machine.warrantyStart}" />
						<h:outputText value="Gewährleistungsende" />		
						<h:inputText value="#{machine.warrantyEnd}" />
						<h:outputText value="Inbetriebnahme" />		
						<h:inputText value="#{machine.startUpDate}" />							
					</h:panelGrid>
					<h:panelGrid columns="1" styleClass="formTable" rowClasses="formTableRowLabel, formTableRowInput">				
						<h:outputText value="Maschineninfo" />		
						<h:inputText value="#{machine.info}" />
					</h:panelGrid>
				</h:panelGrid>
				<br />
				<h:commandButton action="#{selectMachine.saveChanges}" value="#{messages.misc_Save}" type="submit"/>
				<r:messages />
			</h:form>
		</c:otherwise>
	</c:choose>
</ui:composition>

Vielen Dank für Eure Hilfe!

brunce
 
Schon blöd das ich fast ne Woche für das Problem aufgewendet habe und mich wunderte warum es immer da war.

Des Rätsels Lösung: Keine <form> in eine <form> packen.
 
Zurück