{"id":2429,"date":"2017-06-12T17:04:40","date_gmt":"2017-06-12T15:04:40","guid":{"rendered":"http:\/\/hasselba.ch\/blog\/?p=2429"},"modified":"2017-06-12T17:05:56","modified_gmt":"2017-06-12T15:05:56","slug":"quick-n-dirty-hotfix-for-datetimehelper","status":"publish","type":"post","link":"https:\/\/hasselba.ch\/blog\/?p=2429","title":{"rendered":"Quick-n-Dirty: Hotfix for DateTimeHelper"},"content":{"rendered":"<p>This weekend I stumbled over a bug of the <em>DateTimeHelper<\/em>: If the value of the field is empty, no actions and\/or action listeners connected with a managed bean will be executed anymore.<\/p>\n<p>Here is an example of a small XPage to illustrate the problem:<\/p>\n<pre><code>&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;xp:view xmlns:xp=\"http:\/\/www.ibm.com\/xsp\/core\"&gt;\r\n \r\n    &lt;xp:label \r\n        value=\"#{javascript:java.lang.System.currentTimeMillis()}\" id=\"labelNow\" \/&gt;\r\n\r\n     &lt;xp:inputText id=\"inputTextDT\" value=\"#{myBean.valueDT}\"&gt;\r\n         &lt;xp:this.converter&gt;\r\n             &lt;xp:convertDateTime type=\"date\" \/&gt;\r\n         &lt;\/xp:this.converter&gt;\r\n         &lt;xp:dateTimeHelper \/&gt;\r\n     &lt;\/xp:inputText&gt;\r\n\r\n    &lt;xp:button id=\"button\" value=\"OK\"&gt;\r\n        &lt;xp:eventHandler\r\n            event=\"onclick\"\r\n            submit=\"true\"\r\n            refreshMode=\"partial\"\r\n            refreshId=\"labelNow\"\r\n            actionListener=\"#{myBean.action}\" \/&gt;\r\n     &lt;\/xp:button&gt;\r\n\r\n&lt;\/xp:view&gt;<\/code><\/pre>\n<p>It does not matter if you set the <em>disableValidators<\/em> property for the text field to <em>true<\/em>, even an <em>immediate=true<\/em> won&#8217;t help here. The reason for the problem is that the renderer of the <em>dateTimeHelper\u00a0<\/em>always uses the attached converter and fails with a null pointer exception if the value is empty (this infringes the JSF specification, but IBM has implemented it this way).<\/p>\n<p>The workaround for this problem is to overwrite the existing renderer class and handle the NPE by yourself:<\/p>\n<pre><code>package ch.hasselba.xpages.renderer;\r\n\r\nimport javax.faces.component.UIComponent;\r\nimport javax.faces.context.FacesContext;\r\nimport javax.faces.convert.ConverterException;\r\npublic class DateTimeHelperRenderer\r\n    extends com.ibm.xsp.renderkit.dojo.DateTimeHelperRenderer{\r\n\r\n\u00a0\u00a0\u00a0 public Object getConvertedValue(FacesContext fc, UIComponent uiComponent, Object obj)\r\n    \u00a0 \u00a0 throws ConverterException\u00a0 {\r\n\r\n         \u00a0Object result = super.getConvertedValue(fc, uiComponent, obj);\r\n\r\n         \u00a0if( result == null )\r\n           \u00a0return new Object();\r\n\r\n       \u00a0 \u00a0return result;\r\n  \u00a0 }\r\n}<\/code><\/pre>\n<p>The renderer must now be registered in <em>faces-config.xml<\/em>:<\/p>\n<pre><code>&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;&lt;?xml version=\"1.0\" encoding=\"UTF-8\"?&gt;\r\n&lt;faces-config&gt;\r\n  &lt;render-kit&gt;\r\n    &lt;renderer&gt;\r\n      &lt;component-family&gt;javax.faces.Input&lt;\/component-family&gt;\r\n      &lt;renderer-type&gt;com.ibm.xsp.DateTimeHelper&lt;\/renderer-type&gt;\r\n      &lt;renderer-class&gt;ch.hasselba.xpages.renderer.DateTimeHelperRenderer&lt;\/renderer-class&gt;\r\n    &lt;\/renderer&gt;\r\n  &lt;\/render-kit&gt;\r\n&lt;\/faces-config&gt;\r\n<\/code><\/pre>\n<p>Now the problem is solved, the managed bean&#8217;s action get executed even if the value is empty.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>This weekend I stumbled over a bug of the DateTimeHelper: If the value of the field is empty, no actions and\/or action listeners connected with a managed bean will be executed anymore. Here is an example of a small XPage &hellip; <a href=\"https:\/\/hasselba.ch\/blog\/?p=2429\">Weiterlesen <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[89,26,74],"tags":[47,15,7,31,86,3],"class_list":["post-2429","post","type-post","status-publish","format-standard","hentry","category-java","category-jsf","category-xpages","tag-9-0","tag-bug","tag-domino","tag-java","tag-jsf","tag-xpages"],"_links":{"self":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2429","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2429"}],"version-history":[{"count":5,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2429\/revisions"}],"predecessor-version":[{"id":2435,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=\/wp\/v2\/posts\/2429\/revisions\/2435"}],"wp:attachment":[{"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2429"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2429"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/hasselba.ch\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2429"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}