Si estamos instanciando nuestros componentes programáticamente desde Java, ¿cómo enlazar los eventos javascript a un comportamiento de RichFaces?
Si fuera sólo un evento javascript, la mayoría de las clases herederas de UIComponent tienen modos para ello
HtmlInputText txt = new HtmlInputText(); txt.setOnclick("alert('Was ist der weld?')");
Pero no podemos usar EL en javascript, el cual queda literal
<a onclick="#{rich:component('editPropiedad')}.show()">...</a>;
sino que cuando en un tag especifico, por ejemplo,
<a onclick="#{rich:component('editPropiedad')}.show()">...</a>
estoy dándole una instrucción al tiempo de armado de la página (no sé qué fase exactamente), la cual de hecho en HTML queda como una función que la librería de RichFaces comprenderá
<a onclick="RichFaces.ajax('form:tablaPopup1:0:j_idt427',event,{'incId':'1'} ); return false;">...</a>
Por ende podríamos pensar que hay que setearlo como ValueExpression (ver artículo al respecto)
ValueExpression evento = expresiones.getExpressionFactory().createValueExpression(expresiones.getELContext(), "#{rich:component('id')}.show()}", String.class); txt.setValueExpression("onclick", evento);
pero ésto me lenzará una excepción
javax.el.ELException: Función "rich:component" no hallada
Tampoco, si quisiéramos añadir un rich:componentControl programáticamente, pareciera que éste tenga un componentType, sino que de hecho en los foros se recomienda usar el EL anterior >>
Entonces, ¿qué opción queda?
¡Había olvidado la API javaScript >>!
Lo que en RichFaces 4 se escribe
txt.setOnclick("RichFaces.$('id').show();");
y funciona, pero no si el componente está disabled!!!!
En este caso lo más elegante sería rodear el componente con un <span/> y a éste setearle el onclick
(Como el HtmlOutputPanel no tiene soporte para eventos, lo intenté con UIOutputPanel) pero sin suerte:
UIOutputPanel spanTag = (UIOutputPanel)app.createComponent(UIOutputPanel.COMPONENT_TYPE); txt.setDisabled(true); spanTag.getChildren().add(txt); spanTag.setOnclick("RichFaces.$('id').show();");
como el evento se genera en el elemento que está disabled, no se propagará por el árbol DOM así es que es lo mismo…
Ahora, esto sí funciona si es que en vez de setDisabled usamos setReadonly…
txt.setReadonly(true);
salvo que readonly no aplica para HtmSelectOneMenu ¡¡¡¡¡