Компонентный компонент JSF для ввода подтверждения адреса
Я хочу написать составной компонент для возможности ввода адреса. Кроме того, я хочу выполнить некоторую проверку при отправке, и если проверка не удалась, я хочу перерисовать часть составного компонента. Я действительно не знаю, как архивировать это. Моя идея состоит в том, чтобы подтвердить в getConvertedValue
метод и просто установить флаг и бросить validatorException
если проверка не удалась.
Я уже много читал о составных компонентах в блоге balusC, но не нашел подходящего способа архивировать то, что я хочу.
Это мой код до сих пор:addressInput:
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:rich="http://richfaces.org/rich"
xmlns:a4j="http://richfaces.org/a4j" xmlns:p="http://primefaces.org/ui"
xmlns:composite="http://java.sun.com/jsf/composite">
<composite:interface componentType="locationInput2">
<composite:attribute name="value" />
</composite:interface>
<composite:implementation>
<span id="#{cc.id}"> <p:panelGrid styleClass="noPadding"
id="grd">
<p:row>
<p:column>
<p:outputLabel value="Straße" for="street " />
</p:column>
<p:column>
<p:inputText id="street" binding="#{cc.street}" size="30"
required="true"
styleClass="#{not component.valid ? 'ui-input-invalid' : ''}" />
<p:outputLabel value="Nr." for="houseNr" />
<p:inputText id="houseNr" binding="#{cc.houseNr}" size="4"
required="true"
styleClass="#{not component.valid ? 'ui-input-invalid' : ''}" />
</p:column>
<p:column style="width:20px" />
<p:column>
<p:outputLabel value="PLZ" for="zipCode" />
</p:column>
<p:column>
<p:inputText id="zipCode" binding="#{cc.zipCode}" size="30"
required="true"
styleClass="#{not component.valid ? 'ui-input-invalid' : ''}" />
</p:column>
</p:row>
<p:row>
<p:column>
<p:outputLabel value="Stadt" for="city" />
</p:column>
<p:column>
<p:inputText id="city" binding="#{cc.city}" size="30"
required="true"
styleClass="#{not component.valid ? 'ui-input-invalid' : ''}" />
</p:column>
<p:column style="width:20px" />
<p:column>
<p:outputLabel value="Land" for="country" />
</p:column>
<p:column>
<p:autoComplete id="country" forceSelection="true" dropdown="true"
styleClass="#{not component.valid ? 'ui-input-invalid' : ''}"
required="true" cache="true" binding="#{cc.country}"
completeMethod="#{countryBean.complete}" var="entry"
scrollHeight="200" itemValue="#{entry}" itemLabel="#{entry.name}"
converter="countryConverter" />
</p:column>
</p:row>
</p:panelGrid>
<p:panel id="test" rendered="#{cc.failed}">
<p:outputLabel value="VALIDATION FAILED CONTENT"/>
<p:selectBooleanCheckbox/>
</p:panel>
</span>
</composite:implementation>
</html>
FacesComponent:
package com.hji.tis.ui.util.customComponents;
import java.io.IOException;
import javax.faces.application.FacesMessage;
import javax.faces.component.FacesComponent;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIInput;
import javax.faces.component.UINamingContainer;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.validator.ValidatorException;
import javax.inject.Inject;
import lombok.Getter;
import lombok.Setter;
import org.primefaces.component.autocomplete.AutoComplete;
import com.hji.tis.domain.model.location.GeoService;
import com.hji.tis.domain.model.location.Location;
@FacesComponent("locationInput2")
public class LocationInput2 extends UIInput implements NamingContainer {
public enum LOCATION_TYPE {
UNKNOWN, INPUT, CORRECTED;
}
@Getter
@Setter
UIInput street, houseNr, zipCode, city;
@Getter
@Setter
AutoComplete country;
@Getter
@Setter
private boolean failed;
@Inject
private GeoService geoService;
@Override
public String getFamily() {
return UINamingContainer.COMPONENT_FAMILY;
}
@Override
public void encodeBegin(FacesContext context) throws IOException {
Location location = (Location) getAttributes().get("value");
if (location != null) {
street.setValue(location.getAddress().getStreet());
houseNr.setValue(location.getAddress().getHouseNr());
zipCode.setValue(location.getAddress().getZipCode());
city.setValue(location.getAddress().getCity());
Converter converter = country.getConverter();
country.setValue(converter.getAsObject(context, country, location.getAddress().getCountry()));
}
super.encodeBegin(context);
}
@Override
public Object getSubmittedValue() {
return (Location) getAttributes().get("value");
}
@Override
protected Object getConvertedValue(FacesContext context, Object submittedValue) {
// DO THE VALIDATION THINGS, EG. check if houseNr is only digits. If
// failed then do the following things:
failed = true;
// HERE I WANT TO SET A FLAG WHICH SHOULD SHOW AN ADDITIONAL FIELD IN
// THE XHTML IF THE VALIDATION FAILS.
throw new ValidatorException(new FacesMessage());
// Otherwise just return the value.
// return submittedValue;
}
}
Компонент должен работать следующим образом: введите местоположение => нажмите сохранить (вне компонента) => проверить, можно ли кодировать местоположение (через веб-сервис) => если да, вернуть местоположение, в противном случае проверить, есть ли какое-либо предложение или если адрес просто не кодируемый => если не кодируемый, установите флажок, где вы можете поставить галочку "игнорировать" и вернуть местоположение.
Спасибо!