package org.nocket.component.form.behaviors; import org.apache.wicket.Component; import org.apache.wicket.feedback.FeedbackMessage; import org.apache.wicket.markup.html.form.FormComponent; import org.apache.wicket.markup.transformer.AbstractTransformerBehavior; import org.apache.wicket.util.iterator.ComponentHierarchyIterator; import org.jsoup.Jsoup; import org.jsoup.nodes.Document; import org.jsoup.select.Elements; import org.nocket.component.form.ComponentGroup; import org.nocket.component.select.DMDRadioChoice; import org.slf4j.Logger; import org.slf4j.LoggerFactory; // TODO: Auto-generated Javadoc /** * This behavior adds to a group of the components a paragraph with error * messages coming from these components. * * @author blaz02 * */ public class ValidationTooltipStyleGroupBehavior extends AbstractTransformerBehavior { /** The Constant log. */ final private static Logger log = LoggerFactory.getLogger(ValidationTooltipStyleGroupBehavior.class); /** The Constant serialVersionUID. */ private static final long serialVersionUID = 1L; /** The Constant VALIDATION_ERROR_ICON_CLASS. */ public static final String VALIDATION_ERROR_ICON_CLASS = "icon-validation-error"; /** The Constant BR. */ private final static String BR = "\n"; /** The Constant BEFORE_MESSAGE. */ private final static String BEFORE_MESSAGE = "<span class=\"error-icon\">" + "<i class=\"" + VALIDATION_ERROR_ICON_CLASS + "\" title = \""; /** The Constant BEFORE_CS. */ private final static String BEFORE_CS = "<div class=\"control-group error\">"; /** The Constant AFTER_MESSAGE. */ private final static String AFTER_MESSAGE = "\"></i></span>"; /** The Constant AFTER_CS. */ private final static String AFTER_CS = "</div>"; /* (non-Javadoc) * @see org.apache.wicket.markup.transformer.AbstractTransformerBehavior#transform(org.apache.wicket.Component, java.lang.CharSequence) */ @Override public CharSequence transform(Component component, CharSequence cs) { boolean added = false; StringBuffer messageBuffer = new StringBuffer(BEFORE_MESSAGE); boolean isRadio = false; ComponentHierarchyIterator it = ((ComponentGroup) component).visitChildren(FormComponent.class); for (Component n : it) { FormComponent<?> fc = (FormComponent<?>) n; if (!fc.isValid()) { if (fc instanceof DMDRadioChoice<?>) { isRadio = true; } for (FeedbackMessage message : fc.getFeedbackMessages()) { message.markRendered(); if (added) { messageBuffer.append(BR); } messageBuffer.append(message.getMessage()); added = true; } } } if (!added) { return cs; } messageBuffer.append(AFTER_MESSAGE); StringBuffer b; if (isRadio) { b = buildOutputForRadio(cs, messageBuffer, component); } else { b = buildOutput(cs, messageBuffer); } return b.toString(); } /** * Wenn Radios und Checkboxen mit Wicket und Bootstrap verwendet werden, * darf der Fehlertext nicht wie bei den einzelnen Inputfeldern hinten * angefügt werden, sondern er muss in das Controls-Div hinein operiert. * werden * * <pre> * <div class="control-group error"> * <div wicket:id="genderGroup" class="radio-checkbox-group"><wicket:border> * <wicket:body> * <div class="controls"> * <label class="radio" wicket:id="gender" id="gender"> * <input name="memberpanel:personDataPanel:genderGroup:genderGroup_body:gender" type="radio" value="HERR" id="gender-HERR"/> * <label for="gender-HERR">Man< * HIER MUSS ES HIN * </label> * <input name="memberpanel:personDataPanel:genderGroup:genderGroup_body:gender" type="radio" value="FRAU" id="gender-FRAU"/> * <label for="gender-FRAU">Woman</label> * </label> * </div> * </wicket:body> * </wicket:border> * </div> * * </pre> * * @param cs vorhandener HTML-Code * @param messageBuffer Fehlertexte * @param component the component * @return the string buffer */ private StringBuffer buildOutputForRadio(CharSequence cs, StringBuffer messageBuffer, Component component) { StringBuffer b = new StringBuffer(BEFORE_CS); Document document = Jsoup.parse(cs.toString()); Elements divControls = document.select("div[class*=controls]"); if (divControls == null) { log.debug("Finde kein div[class*=controls] in Komponente = '" + component + "' und Page = '" + component.getPage()); return buildOutput(cs, messageBuffer); } Elements labelRadio = divControls.first().select("label[class*=radio]"); if (labelRadio == null) { log.debug("Finde kein " + "label[class*=radio]" + " in Komponente = '" + component + "' und Page = '" + component.getPage()); return buildOutput(cs, messageBuffer); } Elements label = labelRadio.first().children().select("label"); if (label == null) { log.debug("Finde kein label in Komponente = '" + component + "' und Page = '" + component.getPage()); return buildOutput(cs, messageBuffer); } label.first().append(messageBuffer.toString()); b.append(document.html()); b.append(AFTER_CS); return b; } /** * Builds the output. * * @param cs the cs * @param messageBuffer the message buffer * @return the string buffer */ private StringBuffer buildOutput(CharSequence cs, StringBuffer messageBuffer) { StringBuffer b = new StringBuffer(BEFORE_CS).append(cs); b.append(messageBuffer); b.append(AFTER_CS); return b; } }