WaterMark behavior in ADF
How to create watermark/placeholder effect for input component in ADF
- What is watermark behavior
A watermark typically appears as light gray text within an
input or textarea element whenever the element is empty and does not have
focus. This provides a hint to the user as to what the input or textarea
element is used for, or the type of input that is required.
For example, a search input space sometimes appears at the
top of the page, giving the user quick access to the search functionality.
Oftentimes you will see the word "Search" in light gray text in that
space, and when the user clicks into the entry space, the word disappears. That
is an example of a watermark.
- How to implement
1)
Create
your tag library
First
step is to create tab lib in your project. Just select NewàWebTieràJSPàJSP tag library
·
Select
deployable or project based option
·
Provide
tag lib file name URI and version details
2)
Create
custom behavior implantation class as below
public class AddWaterMark extends oracle.adfinternal.view.faces.taglib.behaviors.BehaviorTag {
public AddWaterMark() {
super();
}
private ValueExpression message;
protected String getBehavior(UIComponent component) {
public AddWaterMark() {
super();
}
private ValueExpression message;
protected String getBehavior(UIComponent component) {
StringBuilder script = new StringBuilder();
script.append("var sourceInput = AdfPage.PAGE.findComponentByAbsoluteId('"+component.getId()+"');");
script.append(" var domElemement = AdfAgent.AGENT.getElementById(sourceInput.getClientId());");
script.append("var targetArray = domElemement.getElementsByTagName('input');");
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
String val = message == null ? "" : ComponentUtils.resolveString(message.getValue(elContext));
script.append("targetArray[0].placeholder = '"+val+"';");
writeJavaScriptToClient(script.toString());
return null;
}
private void writeJavaScriptToClient(String script) {
FacesContext fctx = FacesContext.getCurrentInstance();
ExtendedRenderKitService erks =
Service.getRenderKitService(fctx, ExtendedRenderKitService.class);
erks.addScript(fctx, script);
}
public void setMessage(ValueExpression message) {
this.message = message;
}
}
script.append("var sourceInput = AdfPage.PAGE.findComponentByAbsoluteId('"+component.getId()+"');");
script.append(" var domElemement = AdfAgent.AGENT.getElementById(sourceInput.getClientId());");
script.append("var targetArray = domElemement.getElementsByTagName('input');");
ELContext elContext = FacesContext.getCurrentInstance().getELContext();
String val = message == null ? "" : ComponentUtils.resolveString(message.getValue(elContext));
script.append("targetArray[0].placeholder = '"+val+"';");
writeJavaScriptToClient(script.toString());
return null;
}
private void writeJavaScriptToClient(String script) {
FacesContext fctx = FacesContext.getCurrentInstance();
ExtendedRenderKitService erks =
Service.getRenderKitService(fctx, ExtendedRenderKitService.class);
erks.addScript(fctx, script);
}
public void setMessage(ValueExpression message) {
this.message = message;
}
}
3)
How
to get attribute value of JSP tag in implementation class
- Extend ValueExpression class as below
public abstract class ValueExpressionImpl extends ValueExpression {
@SuppressWarnings("compatibility:-3926981577232418734")
private static final long serialVersionUID = 1L;
public abstract Object getValue(ELContext elContext);
@Override
public Class<?> getExpectedType() {
return Object.class;
}
@Override
public Class<?> getType(ELContext context) {
return Object.class;
}
@Override
public String getExpressionString() {
return null;
}
@Override
public boolean isLiteralText() {
return false;
}
@Override
public void setValue(ELContext context, Object value) {
throw new PropertyNotWritableException();
}
@Override
public boolean isReadOnly(ELContext context) {
return true;
}
@Override
public int hashCode() {
return System.identityHashCode(this);
}
@Override
public boolean equals(Object other) {
return this == other;
}
}
@SuppressWarnings("compatibility:-3926981577232418734")
private static final long serialVersionUID = 1L;
public abstract Object getValue(ELContext elContext);
@Override
public Class<?> getExpectedType() {
return Object.class;
}
@Override
public Class<?> getType(ELContext context) {
return Object.class;
}
@Override
public String getExpressionString() {
return null;
}
@Override
public boolean isLiteralText() {
return false;
}
@Override
public void setValue(ELContext context, Object value) {
throw new PropertyNotWritableException();
}
@Override
public boolean isReadOnly(ELContext context) {
return true;
}
@Override
public int hashCode() {
return System.identityHashCode(this);
}
@Override
public boolean equals(Object other) {
return this == other;
}
}
- Edit the generated TLD file as below
<?xml version = '1.0' encoding = 'windows-1252'?>
<taglib xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1" xmlns="http://java.sun.com/xml/ns/javaee
<taglib xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd"
version="2.1" xmlns="http://java.sun.com/xml/ns/javaee
">
<display-name>Add water mark behavior</display-name>
<tlib-version>1.0</tlib-version>
<short-name>watermark</short-name>
<uri>/webapp/watermark</uri>
<tag>
<description>WaterMark</description>
<name>AddWaterMark</name>
<tag-class>watermark.AddWaterMark</tag-class>
<body-content>JSP</body-content>
<attribute>
<description>Message to show in Place holder</description>
<name>message</name>
<required>true</required>
<deferred-value/>
</attribute>
</tag>
</taglib>
<display-name>Add water mark behavior</display-name>
<tlib-version>1.0</tlib-version>
<short-name>watermark</short-name>
<uri>/webapp/watermark</uri>
<tag>
<description>WaterMark</description>
<name>AddWaterMark</name>
<tag-class>watermark.AddWaterMark</tag-class>
<body-content>JSP</body-content>
<attribute>
<description>Message to show in Place holder</description>
<name>message</name>
<required>true</required>
<deferred-value/>
</attribute>
</tag>
</taglib>
- Create the jar file of the project and consume in different project
Note: it requires Mozilla, Chrome and IE 10 and above.
This is built in functionality in the newer inputText components - for example check the 11.1.1.7 component demo and set the placeholder property - http://jdevadf.oracle.com/faces11117/components/inputText.jspx
ReplyDeleteThanks Shay.
ReplyDeleteThis feature comes in PS6 but in our project we are using jdev 11.1.1.6 and in same version there is not straight forward way to achieve the placeholder requirement. I also followed https://blogs.oracle.com/groundside/entry/placeholder_watermarks_with_adf_11
and he did in Jdev R2 by defining Facelets Tag Lib.
Great work. Useful workaround.
ReplyDeleteThanks for sharing your finding.
Good Kiran P
ReplyDeleteCan you please share your sample workspace
ReplyDeleteThank You.. Kiran.. for posting useful link and ideas
ReplyDelete