[RESOLVIDO]Asterisco em campos required [+JSF]

Pessoal gostaria de saber se tem como colocar um indicador (no caso um asterisco vermelho) para todos os h:outputtexts que tem um for para um input REQUIRED

alguma coisa desse tipo

				<h:outputText for="descricao" value="alguma coisa" />
				<h:inputTextarea id="descricao"
					value="teste" required="true"
					requiredMessage="Requerido!" />

Alguma coisa que dessa para eu fazer num canto soh do codigo que valesse para todos esses casos, tipo seria muito facil, criar um grid e colocar outro output com um asterisco vermelho, mas ae eu teria que sair replicando isso em todos os campos required, eu gostaria que ao lado esquerdo de todos os ‘h:outputText’ que tivessem um ‘for’ para um campo required a aplicacao colocasse um asterisco vermelho

[]'s

Alguem tem uma ideia?

Amigo, quando vi seu tópico também fiquei na dúvida e fui pesquisar.
Acabei achando essa solução: http://www.manuelpalacio.net/blog/?p=108
Não sei se é a melhor, mas funciona.
Também criei este tópico(http://groups.google.com/group/javasf/browse_thread/thread/efddae5098fd3f05?hl=pt-BR) no google group javasf, talvez alguém de lá tenha uma idéia melhor.
Se você encontrar uma solução melhor, não esqueça de compartilhar!

Se estiver utilizando JBoss Seam então você poderia aproveitar o componente s:decorate dele. Ou, se estiver utilizando o Facelets você poderia utilizar o ui:decorate para decorar teus inputs.

Uma maneira mais simples e prática é sobreescrever o renderer do h:outputLabel para que ele resolva isso. Eu já fiz isso há muito tempo numa aplicação, contudo não tenho mais o código comigo, porém a idéia é basicamente o que você disse no primeiro post.

Esse post aqui pode te ajudar,
http://www.jroller.com/HazemBlog/entry/overriding_the_jsf_renderers_the

Abraços e boa sorte.

Opa! Achei perdido no meu e-mail a 1a-versão do renderer, mas até onde lembro ela foi melhorada com o tempo, espero que ajude.
Abraços

[code]

public class MyLabelRenderer extends HtmlLabelRenderer {

protected void encodeBeforeEnd( FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent) throws IOException {
	
	String forAttr = getFor(uiComponent);
	
	if(forAttr!=null) {
		
		UIComponent forComponent = uiComponent.findComponent(forAttr);
		
		if(forComponent instanceof UIInput && ((UIInput) forComponent).isRequired()) {
			writer.startElement(HTML.SPAN_ELEM, null);
			
			writer.writeAttribute(HTML.ID_ATTR,	uiComponent.getClientId(facesContext) + "RequiredLabel",null);
			
			writer.writeAttribute(HTML.CLASS_ATTR, "requiredLabel",null);
			
			writer.writeText("*",null);
			
			writer.endElement(HTML.SPAN_ELEM);
		}
		
	}
}

}[/code]

[quote=rponte]Opa! Achei perdido no meu e-mail a 1a-versão do renderer, mas até onde lembro ela foi melhorada com o tempo, espero que ajude.
Abraços

[code]

public class MyLabelRenderer extends HtmlLabelRenderer {

protected void encodeBeforeEnd( FacesContext facesContext, ResponseWriter writer, UIComponent uiComponent) throws IOException {
	
	String forAttr = getFor(uiComponent);
	
	if(forAttr!=null) {
		
		UIComponent forComponent = uiComponent.findComponent(forAttr);
		
		if(forComponent instanceof UIInput && ((UIInput) forComponent).isRequired()) {
			writer.startElement(HTML.SPAN_ELEM, null);
			
			writer.writeAttribute(HTML.ID_ATTR,	uiComponent.getClientId(facesContext) + "RequiredLabel",null);
			
			writer.writeAttribute(HTML.CLASS_ATTR, "requiredLabel",null);
			
			writer.writeText("*",null);
			
			writer.endElement(HTML.SPAN_ELEM);
		}
		
	}
}

}[/code]
[/quote]

cara valeu!
‘String forAttr = getFor(uiComponent);’
de onde eh esse getFor ?
como eu faria para deixar o asterisco vermelhor por exemplo?

[]'s

Seria o mesmo que fazer isso:

Map<String, Object> attrs = component.getAttributes(); String forAttr = (String) attrs.get("for");

??

** EDIT **
Aqui o que eu fiz ate agora:

public class MyLabelRenderer extends LabelRenderer {

	@Override
	public void encodeBegin(FacesContext context, UIComponent component)
			throws IOException {
		ResponseWriter writer = context.getResponseWriter();

		Map<String, Object> attrs = component.getAttributes();
        String forAttr = (String) attrs.get("for");

        if(forAttr!=null) {
        	UIComponent forComponent = component.findComponent(forAttr);
        	if(forComponent instanceof UIInput && ((UIInput) forComponent).isRequired()) {
        		writer.startElement(HTML.SPAN_ELEM, null);
        		writer.writeAttribute(HTML.ID_ATTR,
        				component.getClientId(context) + "RequiredLabel",null);
        		writer.writeAttribute(HTML.CLASS_ATTR, "requiredLabel",null);
        		writer.writeText("*",null);
        		writer.endElement(HTML.SPAN_ELEM);
        	} 
        }
        
		super.encodeBegin(context, component);
	}
}

Ele esta colocando os * no comeco de todos os output com um for para um required. Agora eu queria fazer 2 perguntas.

  1. para que servem essas linhas?
writer.startElement(HTML.SPAN_ELEM, null);
writer.writeAttribute(HTML.ID_ATTR,
    component.getClientId(context) + "RequiredLabel",null);
writer.writeAttribute(HTML.CLASS_ATTR, "requiredLabel",null);
writer.endElement(HTML.SPAN_ELEM);
  1. Como faco para escrever esse * com algum estilo (vermelho no caso)

[]'s

Resolvido o problema. Adicionei a seguinte linha:

writer.writeAttribute(HTML.STYLE_ATTR, "color:red", null);

EDIT

Ok, ok, agora estou com um probleminha. O renderer nao esta funcionando por exemplo quando o label tem um for para uma ‘rich:listShuttle’. Acredito que esse lista nao seja uma instancia de UIInput

vou tentar alterar o codigo para aceitar esses casos.

EDIT
aqui uma versao que devera funcionar para todos os casos

[code]/**

  • Renderizador customizado de labels.
  • @author eu

*/
public class MyLabelRenderer extends LabelRenderer {

/**
 * Esta método altera todos os componentes texto de umma página que tenham
 * um atributo 'for' que aponta para um outro componente que tenha um
 * atributo required 'true'. Colocando um asterisco vermelho na frente
 * do label.
 * 
 * @param context Contexto JSF.
 * @param component Componente.
 * @throws IOException Caso não consiga escrever na página.
 */
@Override
public final void encodeBegin(final FacesContext context,
		final UIComponent component) throws IOException {
	final ResponseWriter writer = context.getResponseWriter();

	final Map<String, Object> attrs = component.getAttributes();
    final String forAttr = (String) attrs.get("for");

    if (forAttr != null) {
    	final UIComponent forComponent = component.findComponent(forAttr);
    	final Map<String, Object> forAttrs = forComponent.getAttributes();
    	final Boolean required = (Boolean) forAttrs.get("required");
    	if (required != null && required) {
    		writer.startElement(HTML.SPAN_ELEM, null);
    		writer.writeAttribute(HTML.ID_ATTR,
    				component.getClientId(context) + "RequiredLabel", null);
    		writer.writeAttribute(HTML.STYLE_ATTR, "color:red", null);
    		writer.writeAttribute(HTML.CLASS_ATTR, "requiredLabel", null);
    		writer.writeText("*", null);
    		writer.endElement(HTML.SPAN_ELEM);
    	} 
    }
    
	super.encodeBegin(context, component);
}

}[/code]

Boa tarde Srs,

De que pacote pertence esse componente?

writer.startElement(HTML.SPAN_ELEM, null);