Removing Seconds, Minutes and Hours from a WDK Date-Time DocbaseAttribute Value Control

So, you are building a wdk application using docbaseobjects. Good ūüôā But now you want more control on how your datetime attribute is rendered. That what I wanted anyway. So after doing some googling I found a javascript that actually hides the fields after they are rendered.¬† This seemed so ugly to me that I decided to create a custom DateValueTag implementation.

 

How is this accomplished?

I created my own DocbaseAttributeValueTag extension. See below

package my.package;
import java.io.IOException;
import java.util.ArrayList;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.JspWriter;
import com.documentum.fc.common.IDfProperties;
import com.documentum.web.common.WrapperRuntimeException;
import com.documentum.web.form.control.DateInput;
import com.documentum.web.form.control.DateInputTag;
import com.documentum.web.form.control.DateTime;
import com.documentum.web.formext.Trace;
import com.documentum.web.formext.control.docbase.DocbaseAttributeCache;
import com.documentum.web.formext.control.docbase.DocbaseAttributeValue;
import com.documentum.web.formext.control.docbase.DocbaseAttributeValueTag;
/**
 */
public class ShortDateTag
    extends DocbaseAttributeValueTag
{
    protected void renderSingleAttribute( String strFormattedValue, String strValue, boolean bReadonly,
                                          boolean bHasCompleteList, JspWriter out )
        throws IOException, JspTagException
    {
        if ( bReadonly )
        {
            super.renderSingleAttribute( strFormattedValue, strValue, bReadonly, bHasCompleteList, out );
        }
        else
        {
            // render custom date control here
            renderCustomDateTime( strValue, out );
        }
    }
    private void renderCustomDateTime( String strValue, JspWriter out )
    {
        DocbaseAttributeValue value = (DocbaseAttributeValue) getControl();
        String strClass = value.getCssClass();
        String strStyle = value.getCssStyle();
        String strSize = "32";
        DateInputTag tag = new DateInputTag();
        tag.setPageContext( pageContext );
        tag.setParent( this );
        tag.setName( value.getElementName( "value" ) );
        tag.setId( getId() );
        tag.setTooltip( value.getToolTip() );
        if ( strClass != null )
        {
            tag.setCssclass( strClass );
        }
        if ( strSize != null )
        {
            tag.setWidth( strSize );
        }
        if ( strStyle != null )
        {
            tag.setStyle( strStyle );
        }
        DateInput dateTimeObj = (DateInput) tag.getControl();
        if ( !value.isEnabled() )
        {
            dateTimeObj.setEnabled( false );
        }
        else
        {
            dateTimeObj.setEnabled( true );
        }
        java.util.Date date = DateTime.toDate( strValue );
        if ( date != null )
        {
            dateTimeObj.setValue( date );
        }
        dateTimeObj.setIsRemovable( false );
        renderSetEvents( null, value.getVaDependenciesProperties(), out );
        DocbaseAttributeCache
            .updateAttributeAndDependentList( value.getAttribute(), dateTimeObj.getElementName(), null );
        try
        {
            tag.doStartTag();
            tag.doEndTag();
        }
        catch ( JspTagException e )
        {
            throw new WrapperRuntimeException( e );
        }
    }
    /**
     * see com.documentum.web.formext.control.docbase.DocbaseAttributeValueTag
     */
    private void renderSetEvents( String strControlName, IDfProperties dependenciesList, JspWriter out )
    {
        DocbaseAttributeValue value = (DocbaseAttributeValue) getControl();
        ArrayList lisControls = DocbaseAttributeCache.getPostServerEventControls( value.getAttribute(), strControlName,
                                                                                  dependenciesList );
        StringBuffer buf = new StringBuffer( 256 );
        if ( lisControls.size() > 0 )
        {
            buf.append( "<script>" );
            buf.append( "setPostServerEventControls(\"" );
            for ( int i = 0; i < lisControls.size(); i++ )
            {
                if ( i > 0 )
                {
                    buf.append( ",\"" );
                }
                buf.append( (String) lisControls.get( i ) );
                buf.append( "\"" );
            }
            buf.append( ");" );
            buf.append( "</script>" );

        }
    }
}

Now you only have to get the WDK to use the new tag. This is accomplished in a xml file. I created a docbaseattributes.xml and added the lines:

<config version='1.0'>
   <scope type="my_document_type">
      <docbaseobjectconfiguration id='attributes'>
         <names>
            <!-- apply to attribute -->
            <attribute name='senddate'>
               <valuetagclass>my.package.ShortDateTag</valuetagclass>
            </attribute> 
 

That’s it!

Inside WDK DocbaseObject

Last days I’ve been struggling with the dmfx:docbaseobject in the wdk 5.3.

Because I wanted more control on the layout of the attributes, I choose to create the attributes one by one in the jsp, instead of using the attributelist.

Snippet:

<dmfx:docbaseobject name='current_document' />                        
<tr><td>
<dmfx:docbaseattribute name='attr_obj_id' object='current_document' attribute='r_object_id'  col1="</td><td>" />
</td></tr>
<tr><td>
<dmfx:docbaseattribute name='attr_medewerkercode' object='current_document' attribute='medewerkercode' size='12' col1="</td><td>" />
</td></tr>

This piece of code resides in a component-page. I have created a button that refreshes the page and changes the docbaseobject’s id. When re-rendering, the old values of the attributes remain on the page. This has to do with the internal workings of the DocbaseAttributeValueTag.

The problem lies in the renderEnd code, which does something like this:           

DocbaseAttributeValue value = (DocbaseAttributeValue) getControl();
 
if(obj.isADocbaseObjectInstance())
{
  strValue = value.getValue();
  if(strValue == null)
  {
    IObjectAdapter objectAdapter = obj.getObjectAdapter();
    if(objectAdapter != null)
    {
      strValue = getValueFromObjectAdapter(objectAdapter);
    } else
    {
      strValue = getValueFromDocbaseObject();
    }
    value.setValue(strValue);
    bGotDisplayValuesForRepeatingAttr = true;
  }
}

It acutally reads the value directly from it’s control class.¬†But once the value inside the control class gets set to somethinh other than null, the object is no longer updated.

This is how I worked around it.

I created a extra boolean value “m_reloadFromDocbase” in the control class and in the DocbaseAttribute class, and added these lines in the renderEnd

   if (value.getReloadFromDocbase())
      strValue = null;

This ensures the value of the attribute will get reloaded from the docbase.

In the behaviour class that handles thes jsp, the render-code is a little extended:

                DocbaseAttribute dat = (DocbaseAttribute) getControl( "attr_" + attribute, DocbaseAttribute.class );
                dat.setReloadFromDocbase( true );

The attribute comes form analyzing the page, using a FindValidAttribute visitor. If the boolean is set to false, the filled-in value will remain.

If you are interested in more detail, please dorp me a line [still figuring out howto]