Congratulations!

[Valid RSS] This is a valid RSS feed.

Recommendations

This feed is valid, but interoperability with the widest range of feed readers could be improved by implementing the following recommendations.

Source: http://xcellerant.wordpress.com/feed/

  1. <?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
  2. xmlns:content="http://purl.org/rss/1.0/modules/content/"
  3. xmlns:wfw="http://wellformedweb.org/CommentAPI/"
  4. xmlns:dc="http://purl.org/dc/elements/1.1/"
  5. xmlns:atom="http://www.w3.org/2005/Atom"
  6. xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
  7. xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
  8. xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
  9. >
  10.  
  11. <channel>
  12. <title>Xcellerant</title>
  13. <atom:link href="https://xcellerant.wordpress.com/feed/" rel="self" type="application/rss+xml" />
  14. <link>https://xcellerant.wordpress.com</link>
  15. <description>Accelerating XPages Development</description>
  16. <lastBuildDate>Wed, 20 Jul 2016 13:24:35 +0000</lastBuildDate>
  17. <language>en</language>
  18. <sy:updatePeriod>
  19. hourly </sy:updatePeriod>
  20. <sy:updateFrequency>
  21. 1 </sy:updateFrequency>
  22. <generator>http://wordpress.com/</generator>
  23. <cloud domain='xcellerant.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
  24. <image>
  25. <url>https://secure.gravatar.com/blavatar/a7d1f3b2a7a3ab3dd2cdfbe3155a04eb478d60d270f0791e672c6a82326bdb70?s=96&#038;d=https%3A%2F%2Fs0.wp.com%2Fi%2Fbuttonw-com.png</url>
  26. <title>Xcellerant</title>
  27. <link>https://xcellerant.wordpress.com</link>
  28. </image>
  29. <atom:link rel="search" type="application/opensearchdescription+xml" href="https://xcellerant.wordpress.com/osd.xml" title="Xcellerant" />
  30. <atom:link rel='hub' href='https://xcellerant.wordpress.com/?pushpress=hub'/>
  31. <item>
  32. <title>XPages Tip: Adding a Bootstrap Class to All Labels via the Theme (Redux)</title>
  33. <link>https://xcellerant.wordpress.com/2016/07/20/xpages-tip-adding-a-bootstrap-class-to-all-labels-via-the-theme-redux/</link>
  34. <comments>https://xcellerant.wordpress.com/2016/07/20/xpages-tip-adding-a-bootstrap-class-to-all-labels-via-the-theme-redux/#comments</comments>
  35. <dc:creator><![CDATA[Brad Balassaitis]]></dc:creator>
  36. <pubDate>Wed, 20 Jul 2016 11:08:50 +0000</pubDate>
  37. <category><![CDATA[Bootstrap]]></category>
  38. <category><![CDATA[Theme]]></category>
  39. <category><![CDATA[XPages]]></category>
  40. <category><![CDATA[XPages Tip]]></category>
  41. <guid isPermaLink="false">http://xcellerant.net/?p=2893</guid>
  42.  
  43. <description><![CDATA[In this post, I showed how to set all labels in an application to include a class to pick up Bootstrap styling so it could be applied application-wide and not require touching every label control individually. However, there&#8217;s a quirk with label rendering that may make it not apply universally as desired. In this post, [&#8230;]]]></description>
  44. <content:encoded><![CDATA[<p>In this post, I showed how to <a href="https://xcellerant.net/2013/12/04/set-the-bootstrap-class-for-all-multiline-text-fields-and-labels-in-xpages-with-a-theme/"> set all labels in an application to include a class to pick up Bootstrap styling</a> so it could be applied application-wide and not require touching every label control individually. However, there&#8217;s a quirk with label rendering that may make it not apply universally as desired. In this post, I&#8217;ll explain the issue and how to use another theme setting to easily fix it.</p>
  45. <h4>Updating all Labels via the Theme</h4>
  46. <p>This code in the theme will apply the <code>control-label</code> class to all label components in the application. This allows me to apply a Bootstrap style class to all labels without having to update each label control individually on every XPage and custom control. </p>
  47. <pre class="brush: plain; title: ; notranslate">
  48. &lt;control&gt;
  49.  &lt;name&gt;Text.Label&lt;/name&gt;
  50.  &lt;property mode=&quot;concat&quot;&gt;
  51.    &lt;name&gt;styleClass&lt;/name&gt;
  52.    &lt;value&gt;control-label&lt;/value&gt;
  53.  &lt;/property&gt;
  54. &lt;/control&gt;
  55. </pre>
  56. <p>The Bootstrap styling will be applied to <code>label </code>tags that have the <code>control-label</code> class.</p>
  57. <h4>The Problem with Label Rendering</h4>
  58. <p>However, there&#8217;s an issue with the way labels are rendered that may not make it work consistently.</p>
  59. <p>Any labels that do not have a <code>for </code>attribute specified will actually be rendered as <code>span </code>tags and the styling will not be picked up. (Labels that have the <code>for </code>attribute specified will be rendered as <code>label </code>tags and work as expected.)</p>
  60. <p>In another post, I described <a href="https://xcellerant.net/xpages-tip-overriding-concatenating-and-conditionally-adding-control-properties-via-a-theme/">the effects of different modes on theme property application</a>. In this post, we&#8217;ll see a practical example of the effects.</p>
  61. <h4> Theme to the Rescue (Again)</h4>
  62. <p>Fortunately, there&#8217;s an easy way to add another property setting to the theme to handle this. </p>
  63. <p>There isn&#8217;t a <code>tagName </code>attribute on a label, so you can&#8217;t directly modify the output tag this way, but <code>for </code>is a property of the control, so you can use the theme to add it to all labels.</p>
  64. <h4> 1. Overriding the Property</h4>
  65. <p>One option is to override the <code>for </code>property on all labels. Lines 7-10 were added below to do so.</p>
  66. <pre class="brush: plain; title: ; notranslate">
  67. &lt;control&gt;
  68.  &lt;name&gt;Text.Label&lt;/name&gt;
  69.  &lt;property mode=&quot;concat&quot;&gt;
  70.    &lt;name&gt;styleClass&lt;/name&gt;
  71.    &lt;value&gt;control-label&lt;/value&gt;
  72.  &lt;/property&gt;
  73.  &lt;property mode=&quot;override&quot;&gt;
  74.    &lt;name&gt;for&lt;/name&gt;
  75.    &lt;value&gt;dummyTarget&lt;/value&gt;
  76.  &lt;/property&gt;
  77. &lt;/control&gt;
  78. </pre>
  79. <p>This puts the <code>for </code>property in place and assumes it needs to figure out the client-side ID of the element that&#8217;s been specified. This is a dummy value, but it does the job.</p>
  80. <pre class="brush: plain; title: ; notranslate">
  81. &lt;label id=&quot;view:_id1:_id3:_id51:office_Label1&quot; class=&quot;control-label&quot; for=&quot;view:_id1:_id3:_id51:dummyTarget&quot;&gt;Office&lt;/label&gt;
  82. </pre>
  83. <p>However, it does the job too ambitiously. It removes any existing <code>for </code>property, so it would break the association with the specified input control, which may cause other issues with the application and most certainly would cause issues with a screen reader.</p>
  84. <h4> 2. Concatenating the Value</h4>
  85. <p>Changing line 7 to concatenate instead of overriding the value gives us a bit better behavior.</p>
  86. <pre class="brush: plain; title: ; notranslate">
  87. &lt;property mode=&quot;concat&quot;&gt;
  88. </pre>
  89. <p>This mode will append the property value to any value that currently exists for the attribute. It will also add the attribute and value if it doesn&#8217;t exist.</p>
  90. <pre class="brush: plain; title: ; notranslate">
  91. &lt;label id=&quot;view:_id1:_id3:_id51:label17&quot; class=&quot;control-label&quot; for=&quot;view:_id1:_id3:_id51:dummyTarget&quot;&gt;Payment #&lt;/label&gt;
  92. </pre>
  93. <p>This also does the job, but it causes two values to be in the for property if one already existed (although it doesn&#8217;t try to generate a client-side ID when it&#8217;s appended).</p>
  94. <pre class="brush: plain; title: ; notranslate">
  95. &lt;label id=&quot;view:_id1:_id3:_id51:office_Label1&quot; class=&quot;control-label&quot; for=&quot;view:_id1:_id3:_id51:office1 dummyTarget&quot;&gt;Office&lt;/label&gt;
  96. </pre>
  97. <p>This is better than the override method, but still may cause problems.</p>
  98. <h4> 3. Mode not specified</h4>
  99. <p>You can also just not specify the mode.</p>
  100. <pre class="brush: plain; title: ; notranslate">
  101. &lt;property&gt;
  102. </pre>
  103. <p>In this case it only adds the property and value if the property doesn&#8217;t already exist, so it&#8217;s the cleanest solution.</p>
  104. <p>This is an example of a label that already had the <code>for </code>attribute specified. It does not get the new dummy value.</p>
  105. <pre class="brush: plain; title: ; notranslate">
  106. &lt;label id=&quot;view:_id1:_id3:_id51:office_Label1&quot; class=&quot;control-label&quot; for=&quot;view:_id1:_id3:_id51:office1&quot;&gt;Office&lt;/label&gt;
  107. </pre>
  108. <p>This is an example of a label that did not have the <code>for </code>attribute specified:</p>
  109. <pre class="brush: plain; title: ; notranslate">
  110. &lt;label id=&quot;view:_id1:_id3:_id51:requisitionLabel&quot; class=&quot;control-label&quot; for=&quot;view:_id1:_id3:_id51:dummyTarget&quot;&gt;Requisition #&lt;/label&gt;
  111. </pre>
  112. ]]></content:encoded>
  113. <wfw:commentRss>https://xcellerant.wordpress.com/2016/07/20/xpages-tip-adding-a-bootstrap-class-to-all-labels-via-the-theme-redux/feed/</wfw:commentRss>
  114. <slash:comments>1</slash:comments>
  115. <media:content url="https://0.gravatar.com/avatar/fca56da31ba95401a45ec98668f0147f8f3d11756eb88c1d5ed3395c2c661f93?s=96&#38;d=identicon&#38;r=G" medium="image">
  116. <media:title type="html">xcellerant</media:title>
  117. </media:content>
  118. </item>
  119. <item>
  120. <title>XPages Tip: Overriding, Concatenating, and Conditionally Adding Control Properties via a Theme</title>
  121. <link>https://xcellerant.wordpress.com/2016/07/20/overriding-concatenating-conditionally-adding-control-properties-via-a-theme/</link>
  122. <comments>https://xcellerant.wordpress.com/2016/07/20/overriding-concatenating-conditionally-adding-control-properties-via-a-theme/#respond</comments>
  123. <dc:creator><![CDATA[Brad Balassaitis]]></dc:creator>
  124. <pubDate>Wed, 20 Jul 2016 11:07:26 +0000</pubDate>
  125. <category><![CDATA[PSC]]></category>
  126. <category><![CDATA[Theme]]></category>
  127. <category><![CDATA[XPages]]></category>
  128. <category><![CDATA[XPages Tip]]></category>
  129. <guid isPermaLink="false">http://xcellerant.net/?p=2892</guid>
  130.  
  131. <description><![CDATA[Themes are commonly-used in XPages applications to include resources needed throughout an application, but they can also be a powerful tool for consistently applying application-wide control settings. In this post, I&#8217;ll explain the difference between different modes for applying a control property and link to a corresponding post with a practical example. 1. Overriding a [&#8230;]]]></description>
  132. <content:encoded><![CDATA[<p>Themes are commonly-used in XPages applications to include resources needed throughout an application, but they can also be a powerful tool for consistently applying application-wide control settings. In this post, I&#8217;ll explain the difference between different modes for applying a control property and link to a corresponding post with a practical example.</p>
  133. <h4>1. Overriding a Control Property</h4>
  134. <p>In this post, I showed how to use the theme to <a href="https://xcellerant.net/2013/12/04/set-the-bootstrap-class-for-all-multiline-text-fields-and-labels-in-xpages-with-a-theme/">add a class to all labels in an application</a> to pick up Bootstrap styling without having to set the class on each individual label.</p>
  135. <p>Here&#8217;s an example of the theme code to make it happen:</p>
  136. <pre class="brush: plain; title: ; notranslate">
  137. &lt;control&gt;
  138.  &lt;name&gt;Text.Label&lt;/name&gt;
  139.  &lt;property mode=&quot;override&quot;&gt;
  140.    &lt;name&gt;styleClass&lt;/name&gt;
  141.    &lt;value&gt;control-label&lt;/value&gt;
  142.  &lt;/property&gt;
  143. &lt;/control&gt;
  144. </pre>
  145. <p>When a page loads, the theme is applied to the page and all label controls are updated as the page is rendered.</p>
  146. <ul>
  147. <li>Line 2 is directing it to apply to all Label controls throughout the application. (This is using a theme ID that&#8217;s predefined for the label control, as noted in the Mastering XPages book.)</li>
  148. <li>Line 4 specifies that it&#8217;s updating the <code>styleClass </code>property of the controls.</li>
  149. <li>Line 5 specifies the <code>control-label</code> class to add to each label. (This is the class name that Bootstrap styling looks for.)</li>
  150. <li>Line 3 is the variable for this post. This example starts with the setting the override mode. This mode will set the class to the specified value on all label controls, overriding anything that may have been set when the control was added on an XPage or custom control. </li>
  151. </ul>
  152. <h4>2. Concatenating a Control Property</h4>
  153. <p>Instead of overriding the property on all controls, another option is to concatenate the specified value to any existing value specified on each instance of the control.</p>
  154. <pre class="brush: plain; title: ; notranslate">
  155. &lt;property mode=&quot;concat&quot;&gt;
  156. </pre>
  157. <p>In this case, if there was a label control that already had a class specified, the <code>control-label</code> class would be added to it (after a space) so the label would have both classes.</p>
  158. <p>If the label control did not have a class, then the specified class would be added.</p>
  159. <h4>3. Conditionally Applying a Control Property</h4>
  160. <p>The last option is not to specify a mode at all.</p>
  161. <pre class="brush: plain; title: ; notranslate">
  162. &lt;property&gt;
  163. </pre>
  164. <p>In this case, it will not do anything to a label control that already has a class specified, but it will add the specified class to any label control that does not have one.</p>
  165. <p>Take a look at <a href="https://xcellerant.net/2016/07/20/xpages-tip-adding-a-bootstrap-class-to-all-labels-via-the-theme-redux/"></a> for a practical example of each of these methods and how the distinction between these methods matters.</p>
  166. ]]></content:encoded>
  167. <wfw:commentRss>https://xcellerant.wordpress.com/2016/07/20/overriding-concatenating-conditionally-adding-control-properties-via-a-theme/feed/</wfw:commentRss>
  168. <slash:comments>0</slash:comments>
  169. <media:content url="https://0.gravatar.com/avatar/fca56da31ba95401a45ec98668f0147f8f3d11756eb88c1d5ed3395c2c661f93?s=96&#38;d=identicon&#38;r=G" medium="image">
  170. <media:title type="html">xcellerant</media:title>
  171. </media:content>
  172. </item>
  173. <item>
  174. <title>XPages Tip: Displaying Bootstrap Applications Properly on Mobile Devices</title>
  175. <link>https://xcellerant.wordpress.com/2016/05/31/display-bootstrap-applications-properly-on-mobile-devices/</link>
  176. <comments>https://xcellerant.wordpress.com/2016/05/31/display-bootstrap-applications-properly-on-mobile-devices/#comments</comments>
  177. <dc:creator><![CDATA[Brad Balassaitis]]></dc:creator>
  178. <pubDate>Tue, 31 May 2016 11:07:54 +0000</pubDate>
  179. <category><![CDATA[Bootstrap]]></category>
  180. <category><![CDATA[Responsive Design]]></category>
  181. <category><![CDATA[Theme]]></category>
  182. <category><![CDATA[XPages]]></category>
  183. <category><![CDATA[XPages Tip]]></category>
  184. <category><![CDATA[PSC]]></category>
  185. <guid isPermaLink="false">http://xcellerant.net/?p=2880</guid>
  186.  
  187. <description><![CDATA[Do you have a Bootstrap navigation menu in XPages that collapses properly in a full browser but not on a mobile device? You may need to set a meta tag to force it to display properly. In this post, I&#8217;ll show the effects with and without the tag on a mobile device. Navbar Collapsing One [&#8230;]]]></description>
  188. <content:encoded><![CDATA[<p>Do you have a Bootstrap navigation menu in XPages that collapses properly in a full browser but not on a mobile device? You may need to set a meta tag to force it to display properly. In this post, I&#8217;ll show the effects with and without the tag on a mobile device.</p>
  189. <h4>Navbar Collapsing</h4>
  190. <p>One of the great features of Bootstrap is its built-in responsive UI that scales well to work on screens of varying sizes. The navigation bars collapse nicely into the hamburger menus to make better use of available space on smaller devices.</p>
  191. <p>However, in recent testing of an XPages application with a Bootstrap UI, it was noted that the navigation menus did not collapse properly when viewed on a phone. It was a little confusing because it collapsed as expected on a full browser.</p>
  192. <p>When the navigation bar is set up properly, it should collapse properly on its own when the screen width is below 768 px. I verified that there are no CSS rules overruling that cutoff and that 768px is, in fact, the point where the menu collapses on the full browser.</p>
  193. <h4>Bootstrap Navbar Test Page</h4>
  194. <p>To test it out, I tried out the <a href="https://getbootstrap.com/examples/navbar/">Bootstrap Navbar test page</a></p>
  195. <p>On my laptop with a full browser, it showed the navigation normally.</p>
  196. <p><a href="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1a-full-browser-over-768px.png"><img data-attachment-id="2886" data-permalink="https://xcellerant.wordpress.com/2016/05/31/display-bootstrap-applications-properly-on-mobile-devices/nav-collapse-1a-full-browser-over-768px/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1a-full-browser-over-768px.png" data-orig-size="1949,628" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Nav Collapse 1A &#8211; Full Browser Over 768px" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1a-full-browser-over-768px.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1a-full-browser-over-768px.png?w=519" class="aligncenter wp-image-2886 size-large" src="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1a-full-browser-over-768px.png?w=519&#038;h=167" alt="Nav Collapse 1A - Full Browser Over 768px"   srcset="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1a-full-browser-over-768px.png?w=800 800w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1a-full-browser-over-768px.png?w=1600 1600w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1a-full-browser-over-768px.png?w=150 150w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1a-full-browser-over-768px.png?w=300 300w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1a-full-browser-over-768px.png?w=768 768w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1a-full-browser-over-768px.png?w=1024 1024w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
  197. <p>When I shrunk the screen to be less than 768px wide, it collapsed the navigation properly.</p>
  198. <p><a href="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1b-full-browser-under-768px.png"><img data-attachment-id="2885" data-permalink="https://xcellerant.wordpress.com/2016/05/31/display-bootstrap-applications-properly-on-mobile-devices/nav-collapse-1b-full-browser-under-768px/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1b-full-browser-under-768px.png" data-orig-size="774,587" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Nav Collapse 1B &#8211; Full Browser Under 768px" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1b-full-browser-under-768px.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1b-full-browser-under-768px.png?w=519" class="aligncenter wp-image-2885" src="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1b-full-browser-under-768px.png?w=500&#038;h=379" alt="Nav Collapse 1B - Full Browser Under 768px" width="500" height="379" srcset="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1b-full-browser-under-768px.png?w=500&amp;h=379 500w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1b-full-browser-under-768px.png?w=150&amp;h=114 150w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1b-full-browser-under-768px.png?w=300&amp;h=228 300w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1b-full-browser-under-768px.png?w=768&amp;h=582 768w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1b-full-browser-under-768px.png 774w" sizes="(max-width: 500px) 100vw, 500px" /></a></p>
  199. <p>When I checked it on my phone, it was collapsed properly.</p>
  200. <p><a href="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1c-phone-collapsed.png"><img data-attachment-id="2884" data-permalink="https://xcellerant.wordpress.com/2016/05/31/display-bootstrap-applications-properly-on-mobile-devices/nav-collapse-1c-phone-collapsed/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1c-phone-collapsed.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Nav Collapse 1C &#8211; Phone &#8211; Collapsed" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1c-phone-collapsed.png?w=169" data-large-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1c-phone-collapsed.png?w=519" class="aligncenter wp-image-2884" src="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1c-phone-collapsed.png?w=400&#038;h=711" alt="Nav Collapse 1C - Phone - Collapsed" width="400" height="711" srcset="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1c-phone-collapsed.png?w=400 400w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1c-phone-collapsed.png?w=84 84w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1c-phone-collapsed.png?w=169 169w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1c-phone-collapsed.png 720w" sizes="(max-width: 400px) 100vw, 400px" /></a></p>
  201. <h4>Test Page in XPages</h4>
  202. <p>I copied the div that contains the navigation from that test page and pasted into an XPage in my application to see how it worked.</p>
  203. <p>It collapsed as expected in a full browser but not on the phone.</p>
  204. <p><a href="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2a-phone-not-collapsed-in-xpages.png"><img loading="lazy" data-attachment-id="2883" data-permalink="https://xcellerant.wordpress.com/2016/05/31/display-bootstrap-applications-properly-on-mobile-devices/nav-collapse-2a-phone-not-collapsed-in-xpages/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2a-phone-not-collapsed-in-xpages.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Nav Collapse 2A &#8211; Phone &#8211; NOT Collapsed in XPages" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2a-phone-not-collapsed-in-xpages.png?w=169" data-large-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2a-phone-not-collapsed-in-xpages.png?w=519" class="aligncenter wp-image-2883" src="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2a-phone-not-collapsed-in-xpages.png?w=400&#038;h=711" alt="Nav Collapse 2A - Phone - NOT Collapsed in XPages" width="400" height="711" srcset="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2a-phone-not-collapsed-in-xpages.png?w=400&amp;h=711 400w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2a-phone-not-collapsed-in-xpages.png?w=84&amp;h=150 84w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2a-phone-not-collapsed-in-xpages.png?w=169&amp;h=300 169w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2a-phone-not-collapsed-in-xpages.png 720w" sizes="(max-width: 400px) 100vw, 400px" /></a></p>
  205. <p>It is also apparent that the page has been scaled so that it fits fully on the phone.</p>
  206. <p>To verify this, I put a button on the page to tell me the screen width. As expected, it showed a width &gt; 768 px, which is why it did not collapse the menus. It scaled the entire page to fit on the screen, so it did not fall below the threshold of the responsive design media queries.</p>
  207. <p><a href="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2b-phone-screen-width.png"><img loading="lazy" data-attachment-id="2882" data-permalink="https://xcellerant.wordpress.com/2016/05/31/display-bootstrap-applications-properly-on-mobile-devices/nav-collapse-2b-phone-screen-width/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2b-phone-screen-width.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Nav Collapse 2B &#8211; Phone &#8211; Screen Width" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2b-phone-screen-width.png?w=169" data-large-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2b-phone-screen-width.png?w=519" class="aligncenter wp-image-2882" src="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2b-phone-screen-width.png?w=400&#038;h=711" alt="Nav Collapse 2B - Phone - Screen Width" width="400" height="711" srcset="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2b-phone-screen-width.png?w=400&amp;h=711 400w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2b-phone-screen-width.png?w=84&amp;h=150 84w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2b-phone-screen-width.png?w=169&amp;h=300 169w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2b-phone-screen-width.png 720w" sizes="(max-width: 400px) 100vw, 400px" /></a></p>
  208. <p>(This is on a Samsung Galaxy. An iPhone showed it to be roughly 900px.)</p>
  209. <p>And this is just a simple page. Imagine how that looks with a much bigger XPage!</p>
  210. <h4>The Difference</h4>
  211. <p>Ultimately, the main difference is that the Bootstrap test page contains a meta tag to make sure the device doesn&#8217;t shrink to fit the entire page on the screen.</p>
  212. <pre class="brush: plain; title: ; notranslate">
  213. &lt;meta name=&quot;viewport&quot; content=&quot;width=device-width, initial-scale=1&quot;&gt;
  214. </pre>
  215. <p>In XPages, this can be set at the page level, but it&#8217;s easiest to do it application-wide via a theme, within a resources tag.</p>
  216. <pre class="brush: plain; title: ; notranslate">
  217. &lt;resources&gt;
  218.  &lt;metaData&gt;
  219.    &lt;name&gt;viewport&lt;/name&gt;
  220.    &lt;content&gt;width=device-width, initial-scale=1.0&lt;/content&gt;
  221.  &lt;/metaData&gt;
  222. &lt;/resources&gt;
  223. </pre>
  224. <p>Now, when I reload the Bootstrap test page, it is displayed properly on the phone.</p>
  225. <p><a href="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-3-phone-collapsed-in-xpages.png"><img loading="lazy" data-attachment-id="2881" data-permalink="https://xcellerant.wordpress.com/2016/05/31/display-bootstrap-applications-properly-on-mobile-devices/nav-collapse-3-phone-collapsed-in-xpages/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-3-phone-collapsed-in-xpages.png" data-orig-size="720,1280" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Nav Collapse 3 &#8211; Phone &#8211; Collapsed in XPages" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-3-phone-collapsed-in-xpages.png?w=169" data-large-file="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-3-phone-collapsed-in-xpages.png?w=519" class="aligncenter wp-image-2881" src="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-3-phone-collapsed-in-xpages.png?w=400&#038;h=711" alt="Nav Collapse 3 - Phone - Collapsed in XPages" width="400" height="711" srcset="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-3-phone-collapsed-in-xpages.png?w=400&amp;h=711 400w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-3-phone-collapsed-in-xpages.png?w=84&amp;h=150 84w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-3-phone-collapsed-in-xpages.png?w=169&amp;h=300 169w, https://xcellerant.files.wordpress.com/2016/05/nav-collapse-3-phone-collapsed-in-xpages.png 720w" sizes="(max-width: 400px) 100vw, 400px" /></a></p>
  226. <p>The button showing the screen with on the phone now shows it to be 360px wide.</p>
  227. ]]></content:encoded>
  228. <wfw:commentRss>https://xcellerant.wordpress.com/2016/05/31/display-bootstrap-applications-properly-on-mobile-devices/feed/</wfw:commentRss>
  229. <slash:comments>2</slash:comments>
  230. <media:content url="https://0.gravatar.com/avatar/fca56da31ba95401a45ec98668f0147f8f3d11756eb88c1d5ed3395c2c661f93?s=96&#38;d=identicon&#38;r=G" medium="image">
  231. <media:title type="html">xcellerant</media:title>
  232. </media:content>
  233.  
  234. <media:content url="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1a-full-browser-over-768px.png?w=800" medium="image">
  235. <media:title type="html">Nav Collapse 1A - Full Browser Over 768px</media:title>
  236. </media:content>
  237.  
  238. <media:content url="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1b-full-browser-under-768px.png" medium="image">
  239. <media:title type="html">Nav Collapse 1B - Full Browser Under 768px</media:title>
  240. </media:content>
  241.  
  242. <media:content url="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-1c-phone-collapsed.png?w=576" medium="image">
  243. <media:title type="html">Nav Collapse 1C - Phone - Collapsed</media:title>
  244. </media:content>
  245.  
  246. <media:content url="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2a-phone-not-collapsed-in-xpages.png" medium="image">
  247. <media:title type="html">Nav Collapse 2A - Phone - NOT Collapsed in XPages</media:title>
  248. </media:content>
  249.  
  250. <media:content url="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-2b-phone-screen-width.png" medium="image">
  251. <media:title type="html">Nav Collapse 2B - Phone - Screen Width</media:title>
  252. </media:content>
  253.  
  254. <media:content url="https://xcellerant.files.wordpress.com/2016/05/nav-collapse-3-phone-collapsed-in-xpages.png" medium="image">
  255. <media:title type="html">Nav Collapse 3 - Phone - Collapsed in XPages</media:title>
  256. </media:content>
  257. </item>
  258. <item>
  259. <title>Efficiently Keeping an XPages Session Alive with JSON RPC</title>
  260. <link>https://xcellerant.wordpress.com/2016/05/25/efficiently-keeping-session-alive-json-rpc/</link>
  261. <comments>https://xcellerant.wordpress.com/2016/05/25/efficiently-keeping-session-alive-json-rpc/#comments</comments>
  262. <dc:creator><![CDATA[Brad Balassaitis]]></dc:creator>
  263. <pubDate>Wed, 25 May 2016 11:07:07 +0000</pubDate>
  264. <category><![CDATA[Browser Session]]></category>
  265. <category><![CDATA[JSON RPC]]></category>
  266. <category><![CDATA[XPages]]></category>
  267. <category><![CDATA[XPages Tip]]></category>
  268. <guid isPermaLink="false">http://xcellerant.net/?p=2862</guid>
  269.  
  270. <description><![CDATA[In my last post, I talked about the difference between two reasons that a user may be prompted to login again while using an XPages application: idle session timeouts and LTPA token expiration. There are a variety of ways to programmatically prevent an browser session from timing out due to inactivity. In this post, I&#8217;ll [&#8230;]]]></description>
  271. <content:encoded><![CDATA[<p>In my <a href="http://xcellerant.net/browser-session-lifespan/">last post</a>, I talked about the difference between two reasons that a user may be prompted to login again while using an XPages application: idle session timeouts and LTPA token expiration. There are a variety of ways to programmatically prevent an browser session from timing out due to inactivity. In this post, I&#8217;ll show how to do it with JSON-RPC and why I prefer it to the standard methods.</p>
  272. <h4>Keeping the Session Alive</h4>
  273. <p>The Keep Session Alive control (<code>xe:keepSessionAlive</code>) in the extension library was designed to make it easy to prevent idle session timeouts; all you have to do is drop the control onto a page and optionally set the refresh period and it will send requests to keep the session alive.</p>
  274. <p>In earlier versions of Notes/Domino, this would not be available without the extension library, which was a limiting factor in many situations. It&#8217;s built into version 9+, so it&#8217;s more readily available.</p>
  275. <p>Other solutions popped up for those without the extension library (and to work around an <a href="https://xomino.com/2012/09/13/keeping-your-xpage-session-alive-without-keepsessionalive/">earlier bug in the control</a>, including <a href="https://openntf.org/XSnippets.nsf/snippet.xsp?id=keeping-your-xpage-session-alive-%E2%80%93-without-keepsessionalive">Mark Roden&#8217;s XSnippet</a>. In this solution, a timer is set to periodically trigger a partial refresh of an empty div in order to send a request to the server and keep the session alive.</p>
  276. <p>This works well and is easy to add to any application.</p>
  277. <p>However, while it can be set to run very infrequently, the partial refresh is more overhead than necessary. It only refreshes a single empty DIV tag, but it&#8217;s still posting the entire form and causing the entire component tree to go through most of the life JSF lifecycle. If the user happens to be viewing the page, the responsiveness may lag due to the synchronous processing and refresh.</p>
  278. <p><a href="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2a-keep-session-alive-xsp-partial-refresh.png"><img loading="lazy" data-attachment-id="2874" data-permalink="https://xcellerant.wordpress.com/2016/05/25/efficiently-keeping-session-alive-json-rpc/keep-alive-2a-keep-session-alive-xsp-partial-refresh/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2a-keep-session-alive-xsp-partial-refresh.png" data-orig-size="390,326" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Keep Alive 2A &#8211; Keep Session Alive XSP partial refresh" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2a-keep-session-alive-xsp-partial-refresh.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2a-keep-session-alive-xsp-partial-refresh.png?w=390" class="aligncenter wp-image-2874 size-medium" src="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2a-keep-session-alive-xsp-partial-refresh.png?w=300&#038;h=251" alt="Keep Alive 2A - Keep Session Alive XSP partial refresh" width="300" height="251" srcset="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2a-keep-session-alive-xsp-partial-refresh.png?w=300 300w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-2a-keep-session-alive-xsp-partial-refresh.png?w=150 150w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-2a-keep-session-alive-xsp-partial-refresh.png 390w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
  279. <p>(In contrast, the Keep Session Alive control appears to be efficient, sending a GET request and getting a minimal response.)</p>
  280. <p><a href="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2b-keep-session-alive-control.png"><img loading="lazy" data-attachment-id="2875" data-permalink="https://xcellerant.wordpress.com/2016/05/25/efficiently-keeping-session-alive-json-rpc/keep-alive-2b-keep-session-alive-control/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2b-keep-session-alive-control.png" data-orig-size="835,93" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Keep Alive 2B &#8211; Keep Session Alive control" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2b-keep-session-alive-control.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2b-keep-session-alive-control.png?w=519" class="aligncenter size-full wp-image-2875" src="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2b-keep-session-alive-control.png?w=519" alt="Keep Alive 2B - Keep Session Alive control"   srcset="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2b-keep-session-alive-control.png?w=800&amp;h=89 800w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-2b-keep-session-alive-control.png?w=150&amp;h=17 150w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-2b-keep-session-alive-control.png?w=300&amp;h=33 300w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-2b-keep-session-alive-control.png?w=768&amp;h=86 768w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-2b-keep-session-alive-control.png 835w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
  281. <h4>RPC Efficiency</h4>
  282. <p>My first thought when looking for a more efficient solution was, at minimum, to use the code to trigger an even that for which I could also enable partial execution <a href="http://www.intec.co.uk/understanding-partial-execution-part-three-jsf-lifecycle/">(explained really well here by Paul Withers)</a> to limit the scope of the processing to make it much more efficient.</p>
  283. <p>However, in thinking through it further, I realized that it would be even more efficient to use JSON RPC, because the amount of information sent is minimal, the response is minimal, and the request is asynchronous, so it doesn&#8217;t have any of the aforementioned issues. (If you&#8217;re not familiar with JSON RPC &#8212; take a look at <a href="http://www.slideshare.net/balassaitis/mwlug-2015-ad114-take-your-xpages-development-to-the-next-level">the first section of this presentation</a> for more information.)</p>
  284. <p>Without further adieu, here is a solution using JSON RPC.</p>
  285. <pre class="brush: plain; title: ; notranslate">
  286. &lt;xe:jsonRpcService id=&quot;jsonRpcService1&quot; serviceName=&quot;rpcUserSession&quot;&gt;
  287.  &lt;xe:this.methods&gt;
  288.    &lt;xe:remoteMethod name=&quot;keepAlive&quot;&gt;
  289.      &lt;xe:this.script&gt;&lt;![CDATA[return '';]]&gt;&lt;/xe:this.script&gt;
  290.    &lt;/xe:remoteMethod&gt;
  291.  &lt;/xe:this.methods&gt;
  292. &lt;/xe:jsonRpcService&gt;
  293. &lt;xp:eventHandler event=&quot;onClientLoad&quot; submit=&quot;false&quot;&gt;
  294.  &lt;xp:this.script&gt;&lt;![CDATA[ setInterval(function(){ console.log('keeping session alive (rpc): ' + new Date()); rpcUserSession.keepAlive(); }, 1500000) ]]&gt;&lt;/xp:this.script&gt;
  295. &lt;/xp:eventHandler&gt;
  296. </pre>
  297. <p>The first 8 lines simply define an rpc service that has a single method that just returns an empty string.</p>
  298. <p>The last 8 lines are an onClientLoad event handler that set a timer to write a message to the browser console and call the RPC method every 25 minutes.</p>
  299. <p>The request sent to the server is minimal&#8230;</p>
  300. <p><a href="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-post.png"><img loading="lazy" data-attachment-id="2873" data-permalink="https://xcellerant.wordpress.com/2016/05/25/efficiently-keeping-session-alive-json-rpc/keep-session-alive-2f-rpc-post/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-post.png" data-orig-size="890,332" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Keep Session Alive 2F &#8211; RPC Post" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-post.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-post.png?w=519" class="aligncenter wp-image-2873" src="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-post.png?w=700&#038;h=261" alt="Keep Session Alive 2F - RPC Post" width="700" height="261" srcset="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-post.png?w=700 700w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-post.png?w=150 150w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-post.png?w=300 300w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-post.png?w=768 768w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-post.png 890w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
  301. <p>&#8230; as is the response.</p>
  302. <p><a href="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-response.png"><img loading="lazy" data-attachment-id="2872" data-permalink="https://xcellerant.wordpress.com/2016/05/25/efficiently-keeping-session-alive-json-rpc/keep-session-alive-2f-rpc-response/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-response.png" data-orig-size="889,239" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Keep Session Alive 2F &#8211; RPC Response" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-response.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-response.png?w=519" class="aligncenter wp-image-2872" src="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-response.png?w=700&#038;h=188" alt="Keep Session Alive 2F - RPC Response" width="700" height="188" srcset="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-response.png?w=700&amp;h=188 700w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-response.png?w=150&amp;h=40 150w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-response.png?w=300&amp;h=81 300w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-response.png?w=768&amp;h=206 768w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-response.png 889w" sizes="(max-width: 700px) 100vw, 700px" /></a></p>
  303. <p>No page processing occurs and the request is asynchronous, so it cannot affect the user.</p>
  304. <p>This can be added to it&#8217;s own custom control and then added to your application&#8217;s page layout control so it&#8217;s available throughout. All you have to do is set the refresh duration, which should be slightly less than the idle session timeout.</p>
  305. <h4>Timeout Handling</h4>
  306. <p>In addition to being more efficient, this method also has the benefit of failing much more gracefully and also providing the ability to handle the timeout.</p>
  307. <p>In my testing the Keep Session Alive control doesn&#8217;t show any error to the user or to the browser console.</p>
  308. <p>The partial refresh method first shows this message&#8230;</p>
  309. <p><a href="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c-partial-refresh-failure.png"><img loading="lazy" data-attachment-id="2871" data-permalink="https://xcellerant.wordpress.com/2016/05/25/efficiently-keeping-session-alive-json-rpc/keep-session-alive-2c-partial-refresh-failure/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c-partial-refresh-failure.png" data-orig-size="566,260" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Keep Session Alive 2C &#8211; Partial Refresh Failure" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c-partial-refresh-failure.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c-partial-refresh-failure.png?w=519" class="aligncenter wp-image-2871" src="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c-partial-refresh-failure.png?w=401&#038;h=184" alt="Keep Session Alive 2C - Partial Refresh Failure" width="401" height="184" srcset="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c-partial-refresh-failure.png?w=401&amp;h=184 401w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c-partial-refresh-failure.png?w=150&amp;h=69 150w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c-partial-refresh-failure.png?w=300&amp;h=138 300w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c-partial-refresh-failure.png 566w" sizes="(max-width: 401px) 100vw, 401px" /></a></p>
  310. <p>&#8230;and then pops up a second error message, saying that there&#8217;s no element to submit, along with the client-side ID of the &lt;div&gt; that&#8217;s the target of the partial refresh.</p>
  311. <p><a href="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c2-partial-refresh-failure-2-no-element-to-submit.png"><img loading="lazy" data-attachment-id="2870" data-permalink="https://xcellerant.wordpress.com/2016/05/25/efficiently-keeping-session-alive-json-rpc/keep-session-alive-2c2-partial-refresh-failure-2-no-element-to-submit/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c2-partial-refresh-failure-2-no-element-to-submit.png" data-orig-size="526,220" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Keep Session Alive 2C2- Partial Refresh Failure 2 &#8211; No Element to Submit" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c2-partial-refresh-failure-2-no-element-to-submit.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c2-partial-refresh-failure-2-no-element-to-submit.png?w=519" class="aligncenter wp-image-2870" src="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c2-partial-refresh-failure-2-no-element-to-submit.png?w=400&#038;h=167" alt="Keep Session Alive 2C2- Partial Refresh Failure 2 - No Element to Submit" width="400" height="167" srcset="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c2-partial-refresh-failure-2-no-element-to-submit.png?w=400&amp;h=167 400w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c2-partial-refresh-failure-2-no-element-to-submit.png?w=150&amp;h=63 150w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c2-partial-refresh-failure-2-no-element-to-submit.png?w=300&amp;h=125 300w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c2-partial-refresh-failure-2-no-element-to-submit.png 526w" sizes="(max-width: 400px) 100vw, 400px" /></a></p>
  312. <p>This is an ugly way to fail.</p>
  313. <p>One of the benefits of the RPC method is that it fails more gracefully AND you can trap the error and handle it however you&#8217;d like.</p>
  314. <p>Here&#8217;s the error message that is displayed in the browser console when the session ends due to the machine going to sleep:</p>
  315. <p><a href="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep.png"><img loading="lazy" data-attachment-id="2868" data-permalink="https://xcellerant.wordpress.com/2016/05/25/efficiently-keeping-session-alive-json-rpc/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep.png" data-orig-size="1208,23" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Keep Session Alive 2D &#8211; RPC Post Failure Due to Machine Going to Sleep" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep.png?w=519" class="aligncenter size-full wp-image-2868" src="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep.png?w=519" alt="Keep Session Alive 2D - RPC Post Failure Due to Machine Going to Sleep"   srcset="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep.png?w=800&amp;h=15 800w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep.png?w=150&amp;h=3 150w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep.png?w=300&amp;h=6 300w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep.png?w=768&amp;h=15 768w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep.png?w=1024&amp;h=19 1024w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep.png 1208w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
  316. <p>A different message is returned when it times out due to the expiration of the LTPA token:</p>
  317. <p><a href="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d2-rpc-post-failure-when-timed-out.png"><img loading="lazy" data-attachment-id="2867" data-permalink="https://xcellerant.wordpress.com/2016/05/25/efficiently-keeping-session-alive-json-rpc/keep-session-alive-2d2-rpc-post-failure-when-timed-out/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d2-rpc-post-failure-when-timed-out.png" data-orig-size="1212,19" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Keep Session Alive 2D2 &#8211; RPC Post Failure When Timed Out" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d2-rpc-post-failure-when-timed-out.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d2-rpc-post-failure-when-timed-out.png?w=519" class="aligncenter size-full wp-image-2867" src="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d2-rpc-post-failure-when-timed-out.png?w=519" alt="Keep Session Alive 2D2 - RPC Post Failure When Timed Out"   srcset="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d2-rpc-post-failure-when-timed-out.png?w=800&amp;h=13 800w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d2-rpc-post-failure-when-timed-out.png?w=150&amp;h=2 150w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d2-rpc-post-failure-when-timed-out.png?w=300&amp;h=5 300w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d2-rpc-post-failure-when-timed-out.png?w=768&amp;h=12 768w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d2-rpc-post-failure-when-timed-out.png?w=1024&amp;h=16 1024w, https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d2-rpc-post-failure-when-timed-out.png 1212w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
  318. <p>The user never gets a message. They would just be prompted to login the next time they tried to run any action on the page that required server interaction.</p>
  319. <p>However, as I described in a previous post, you can <a href="https://xcellerant.net/handling-errors-in-an-xpages-rpc-method/">handle errors within an RPC call</a>. You could use this to either display a nicer message to the user or redirect to a login page, either of which allows you to handle it much more gracefully.</p>
  320. ]]></content:encoded>
  321. <wfw:commentRss>https://xcellerant.wordpress.com/2016/05/25/efficiently-keeping-session-alive-json-rpc/feed/</wfw:commentRss>
  322. <slash:comments>1</slash:comments>
  323. <media:content url="https://0.gravatar.com/avatar/fca56da31ba95401a45ec98668f0147f8f3d11756eb88c1d5ed3395c2c661f93?s=96&#38;d=identicon&#38;r=G" medium="image">
  324. <media:title type="html">xcellerant</media:title>
  325. </media:content>
  326.  
  327. <media:content url="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2a-keep-session-alive-xsp-partial-refresh.png?w=300" medium="image">
  328. <media:title type="html">Keep Alive 2A - Keep Session Alive XSP partial refresh</media:title>
  329. </media:content>
  330.  
  331. <media:content url="https://xcellerant.files.wordpress.com/2016/05/keep-alive-2b-keep-session-alive-control.png" medium="image">
  332. <media:title type="html">Keep Alive 2B - Keep Session Alive control</media:title>
  333. </media:content>
  334.  
  335. <media:content url="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-post.png?w=800" medium="image">
  336. <media:title type="html">Keep Session Alive 2F - RPC Post</media:title>
  337. </media:content>
  338.  
  339. <media:content url="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2f-rpc-response.png" medium="image">
  340. <media:title type="html">Keep Session Alive 2F - RPC Response</media:title>
  341. </media:content>
  342.  
  343. <media:content url="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c-partial-refresh-failure.png" medium="image">
  344. <media:title type="html">Keep Session Alive 2C - Partial Refresh Failure</media:title>
  345. </media:content>
  346.  
  347. <media:content url="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2c2-partial-refresh-failure-2-no-element-to-submit.png" medium="image">
  348. <media:title type="html">Keep Session Alive 2C2- Partial Refresh Failure 2 - No Element to Submit</media:title>
  349. </media:content>
  350.  
  351. <media:content url="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d-rpc-post-failure-due-to-machine-going-to-sleep.png" medium="image">
  352. <media:title type="html">Keep Session Alive 2D - RPC Post Failure Due to Machine Going to Sleep</media:title>
  353. </media:content>
  354.  
  355. <media:content url="https://xcellerant.files.wordpress.com/2016/05/keep-session-alive-2d2-rpc-post-failure-when-timed-out.png" medium="image">
  356. <media:title type="html">Keep Session Alive 2D2 - RPC Post Failure When Timed Out</media:title>
  357. </media:content>
  358. </item>
  359. <item>
  360. <title>Browser Session Lifespan &#8211; Idle Session Timeout vs LTPA Token Expiration</title>
  361. <link>https://xcellerant.wordpress.com/2016/05/24/browser-session-lifespan/</link>
  362. <comments>https://xcellerant.wordpress.com/2016/05/24/browser-session-lifespan/#respond</comments>
  363. <dc:creator><![CDATA[Brad Balassaitis]]></dc:creator>
  364. <pubDate>Tue, 24 May 2016 11:07:25 +0000</pubDate>
  365. <category><![CDATA[Browser Session]]></category>
  366. <category><![CDATA[XPages]]></category>
  367. <category><![CDATA[xsp.properties]]></category>
  368. <category><![CDATA[PSC]]></category>
  369. <guid isPermaLink="false">http://xcellerant.net/?p=2852</guid>
  370.  
  371. <description><![CDATA[I recently spent some time investigating a client&#8217;s reports of unexpected behavior with the duration of browser sessions while testing an application on a test server. From time to time, they were required to login even while actively using an application. In this post, I&#8217;ll highlight the difference between an idle session timeout and an [&#8230;]]]></description>
  372. <content:encoded><![CDATA[<p>I recently spent some time investigating a client&#8217;s reports of unexpected behavior with the duration of browser sessions while testing an application on a test server. From time to time, they were required to login even while actively using an application. In this post, I&#8217;ll highlight the difference between an idle session timeout and an LTPA token expiration, which serve different purposes and, in the latter case, may cause frustration if not understood.</p>
  373. <h4>User Expectations</h4>
  374. <p>Most users are familiar with the concept of a browser session timing out if left idle for too long. In this case, websites will generally inform the user that a session has expired and require the user to login again in order to continue.</p>
  375. <p>But users will generally not expect to be required to login again while actively using an application, so it&#8217;s important to understand why it might happen and what you can do about it.</p>
  376. <h4>Idle Session Timeout &#8211; Server</h4>
  377. <p>The Domino server document has a setting to define how long it will take for the session to be automatically logged out due to inactivity. This is configured on the server document: <code>Internet Protocols... &gt; Domino Web Engine &gt; Idle session time-out </code></p>
  378. <p><a href="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1a-server-idle-session-timeout.png"><img loading="lazy" data-attachment-id="2855" data-permalink="https://xcellerant.wordpress.com/2016/05/24/browser-session-lifespan/keep-alive-1a-server-idle-session-timeout/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1a-server-idle-session-timeout.png" data-orig-size="1137,417" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Keep Alive 1A &#8211; Server &#8211; Idle Session Timeout" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1a-server-idle-session-timeout.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1a-server-idle-session-timeout.png?w=519" class="aligncenter size-large wp-image-2855" src="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1a-server-idle-session-timeout.png?w=519&#038;h=190" alt="Keep Alive 1A - Server - Idle Session Timeout"   srcset="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1a-server-idle-session-timeout.png?w=800 800w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-1a-server-idle-session-timeout.png?w=150 150w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-1a-server-idle-session-timeout.png?w=300 300w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-1a-server-idle-session-timeout.png?w=768 768w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-1a-server-idle-session-timeout.png?w=1024 1024w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-1a-server-idle-session-timeout.png 1137w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
  379. <p>The default is 30 minutes.</p>
  380. <h4>Idle Session Timeout &#8211; Application</h4>
  381. <p>There is also an application-level setting for the session timeout, which can be found on the <code>General </code>tab of <code>Xsp Properties</code>.</p>
  382. <p>&nbsp;</p>
  383. <p><a href="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1b-application-idle-session-timeout.png"><img loading="lazy" data-attachment-id="2853" data-permalink="https://xcellerant.wordpress.com/2016/05/24/browser-session-lifespan/keep-alive-1b-application-idle-session-timeout/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1b-application-idle-session-timeout.png" data-orig-size="579,657" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Keep Alive 1B &#8211; Application &#8211; Idle Session Timeout" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1b-application-idle-session-timeout.png?w=264" data-large-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1b-application-idle-session-timeout.png?w=519" class="aligncenter wp-image-2853" src="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1b-application-idle-session-timeout.png?w=400&#038;h=454" alt="Keep Alive 1B - Application - Idle Session Timeout" width="400" height="454" srcset="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1b-application-idle-session-timeout.png?w=400&amp;h=454 400w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-1b-application-idle-session-timeout.png?w=132&amp;h=150 132w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-1b-application-idle-session-timeout.png?w=264&amp;h=300 264w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-1b-application-idle-session-timeout.png 579w" sizes="(max-width: 400px) 100vw, 400px" /></a>This sets the <code>xsp.session.timeout</code> property.</p>
  384. <pre class="brush: plain; title: ; notranslate">
  385. xsp.session.timeout=30
  386. </pre>
  387. <h4>LTPA Token Timeout</h4>
  388. <p>If single sign-on is configured to share the session between multiple servers, a Web Configuration document will define the SSO parameters.</p>
  389. <p>The key setting in this case is the <code>Expiration (minutes)</code> field on the <code>Basics </code>tab of the document. This defines the lifespan of the LTPA token that is issued when the user logs in.</p>
  390. <p><a href="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1c-sso-token-expiration.png"><img loading="lazy" data-attachment-id="2854" data-permalink="https://xcellerant.wordpress.com/2016/05/24/browser-session-lifespan/keep-alive-1c-sso-token-expiration/" data-orig-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1c-sso-token-expiration.png" data-orig-size="657,333" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Keep Alive 1C &#8211; SSO Token Expiration" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1c-sso-token-expiration.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1c-sso-token-expiration.png?w=519" class="aligncenter wp-image-2854" src="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1c-sso-token-expiration.png?w=450&#038;h=228" alt="Keep Alive 1C - SSO Token Expiration" width="450" height="228" srcset="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1c-sso-token-expiration.png?w=450&amp;h=228 450w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-1c-sso-token-expiration.png?w=150&amp;h=76 150w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-1c-sso-token-expiration.png?w=300&amp;h=152 300w, https://xcellerant.files.wordpress.com/2016/05/keep-alive-1c-sso-token-expiration.png 657w" sizes="(max-width: 450px) 100vw, 450px" /></a></p>
  391. <p><em>The important thing to understand is that this has nothing to do with how active or idle the session is. </em></p>
  392. <p>This is a fixed length of time for which the key will be valid. Once it expires, the user will be prompted to login again. This can be very confusing to a user who is actively using the application!</p>
  393. <h4>Improving the Experience</h4>
  394. <p>There are a number of ways to implement controls to keep a session from timing out due to inactivity, but they will have no effect on the expiration of the LTPA token.</p>
  395. <p>In order to prevent users from being frustrated with frequent logouts, some very smart people including <a href="http://stackoverflow.com/questions/13286756/lotus-domino-server-with-kerberos-authentication-and-xpages/13287124#13287124">Per Lausten</a> and <a href="https://www.focul.net/users-losing-authenticated-access-to-xpage-apps-when-using-sso-ltpa-tokens-solved/">Sean Cull</a>, have written about this in years past and have recommended setting the token expiration to a much larger number in order to prevent unexpected behavior. The idle session timeout can still do it&#8217;s job dealing with inactive sessions (and you as a developer can programmatically work to keep them alive if desired).</p>
  396. ]]></content:encoded>
  397. <wfw:commentRss>https://xcellerant.wordpress.com/2016/05/24/browser-session-lifespan/feed/</wfw:commentRss>
  398. <slash:comments>0</slash:comments>
  399. <media:content url="https://0.gravatar.com/avatar/fca56da31ba95401a45ec98668f0147f8f3d11756eb88c1d5ed3395c2c661f93?s=96&#38;d=identicon&#38;r=G" medium="image">
  400. <media:title type="html">xcellerant</media:title>
  401. </media:content>
  402.  
  403. <media:content url="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1a-server-idle-session-timeout.png?w=800" medium="image">
  404. <media:title type="html">Keep Alive 1A - Server - Idle Session Timeout</media:title>
  405. </media:content>
  406.  
  407. <media:content url="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1b-application-idle-session-timeout.png" medium="image">
  408. <media:title type="html">Keep Alive 1B - Application - Idle Session Timeout</media:title>
  409. </media:content>
  410.  
  411. <media:content url="https://xcellerant.files.wordpress.com/2016/05/keep-alive-1c-sso-token-expiration.png" medium="image">
  412. <media:title type="html">Keep Alive 1C - SSO Token Expiration</media:title>
  413. </media:content>
  414. </item>
  415. <item>
  416. <title>XPages Tip: Passing an Array to a Custom Control Property</title>
  417. <link>https://xcellerant.wordpress.com/2016/04/12/xpages-tip-passing-an-array-to-a-custom-control-property/</link>
  418. <comments>https://xcellerant.wordpress.com/2016/04/12/xpages-tip-passing-an-array-to-a-custom-control-property/#comments</comments>
  419. <dc:creator><![CDATA[Brad Balassaitis]]></dc:creator>
  420. <pubDate>Tue, 12 Apr 2016 10:06:20 +0000</pubDate>
  421. <category><![CDATA[Custom Controls]]></category>
  422. <category><![CDATA[SSJS]]></category>
  423. <category><![CDATA[XPages]]></category>
  424. <category><![CDATA[XPages Tip]]></category>
  425. <category><![CDATA[PSC]]></category>
  426. <guid isPermaLink="false">http://xcellerant.net/?p=2842</guid>
  427.  
  428. <description><![CDATA[Custom properties are extremely useful for modular design and reuse by sending custom values into each instance. There are a number of data types that can be selected, but no obvious way to pass an array value. In this post, I&#8217;ll describe the issue and how to work around it. Custom Property Data Types The [&#8230;]]]></description>
  429. <content:encoded><![CDATA[<p>Custom properties are extremely useful for modular design and reuse by sending custom values into each instance. There are a number of data types that can be selected, but no obvious way to pass an array value. In this post, I&#8217;ll describe the issue and how to work around it.</p>
  430. <h4>Custom Property Data Types</h4>
  431. <p>The default data type for a custom property is <code>string</code>.</p>
  432. <p>There are a number of primitive data types available in the dropdown:</p>
  433. <p><a href="https://xcellerant.files.wordpress.com/2016/04/custom-property-primitive-types.png" rel="attachment wp-att-2847"><img loading="lazy" data-attachment-id="2847" data-permalink="https://xcellerant.wordpress.com/2016/04/12/xpages-tip-passing-an-array-to-a-custom-control-property/custom-property-primitive-types/" data-orig-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-primitive-types.png" data-orig-size="538,327" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Custom Property &#8211; Primitive Types" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-primitive-types.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-primitive-types.png?w=519" class="aligncenter wp-image-2847 size-full" src="https://xcellerant.files.wordpress.com/2016/04/custom-property-primitive-types.png?w=519" alt="Custom Property - Primitive Types"   srcset="https://xcellerant.files.wordpress.com/2016/04/custom-property-primitive-types.png 538w, https://xcellerant.files.wordpress.com/2016/04/custom-property-primitive-types.png?w=150&amp;h=91 150w, https://xcellerant.files.wordpress.com/2016/04/custom-property-primitive-types.png?w=300&amp;h=182 300w" sizes="(max-width: 538px) 100vw, 538px" /></a></p>
  434. <p>If you click the folder icons, there are a number of additional options, including Converters, Validators, and other types, but there are no data types for arrays (or vectors or JavaScript objects).</p>
  435. <p><a href="https://xcellerant.files.wordpress.com/2016/04/custom-property-property-types.png" rel="attachment wp-att-2848"><img loading="lazy" data-attachment-id="2848" data-permalink="https://xcellerant.wordpress.com/2016/04/12/xpages-tip-passing-an-array-to-a-custom-control-property/custom-property-property-types/" data-orig-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-property-types.png" data-orig-size="525,643" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Custom Property &#8211; Property Types" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-property-types.png?w=245" data-large-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-property-types.png?w=519" class="aligncenter wp-image-2848 size-full" src="https://xcellerant.files.wordpress.com/2016/04/custom-property-property-types.png?w=519" alt="Custom Property - Property Types"   srcset="https://xcellerant.files.wordpress.com/2016/04/custom-property-property-types.png 525w, https://xcellerant.files.wordpress.com/2016/04/custom-property-property-types.png?w=122&amp;h=150 122w, https://xcellerant.files.wordpress.com/2016/04/custom-property-property-types.png?w=245&amp;h=300 245w" sizes="(max-width: 525px) 100vw, 525px" /></a></p>
  436. <h4>String Data Type</h4>
  437. <p>In this case, I want a property that can accept an array of values.</p>
  438. <p>To test this, I created a simple custom control with two properties, <code>stringProperty </code>and <code>objectProperty</code>, to test how they handle arrays. They both default to <code>string </code>as the data type.</p>
  439. <p><a href="https://xcellerant.files.wordpress.com/2016/04/custom-property-1-custom-property.png" rel="attachment wp-att-2845"><img loading="lazy" data-attachment-id="2845" data-permalink="https://xcellerant.wordpress.com/2016/04/12/xpages-tip-passing-an-array-to-a-custom-control-property/custom-property-1-custom-property/" data-orig-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-1-custom-property.png" data-orig-size="632,298" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Custom Property &#8211; 1 Custom Property" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-1-custom-property.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-1-custom-property.png?w=519" class="aligncenter wp-image-2845 size-full" src="https://xcellerant.files.wordpress.com/2016/04/custom-property-1-custom-property.png?w=519" alt="Custom Property - 1 Custom Property"   srcset="https://xcellerant.files.wordpress.com/2016/04/custom-property-1-custom-property.png 632w, https://xcellerant.files.wordpress.com/2016/04/custom-property-1-custom-property.png?w=150&amp;h=71 150w, https://xcellerant.files.wordpress.com/2016/04/custom-property-1-custom-property.png?w=300&amp;h=141 300w" sizes="(max-width: 632px) 100vw, 632px" /></a></p>
  440. <pre class="brush: plain; title: ; notranslate">
  441. &lt;xc:ccTest&gt;
  442.  &lt;xc:this.stringProperty&gt;&lt;![CDATA[#{javascript:return ['1', '2', '3', '4', '5'];}]]&gt;&lt;/xc:this.stringProperty&gt;
  443.  &lt;xc:this.objectProperty&gt;&lt;![CDATA[#{javascript:return ['1', '2', '3', '4', '5'];}]]&gt;&lt;/xc:this.objectProperty&gt;
  444. &lt;/xc:ccTest&gt;
  445. </pre>
  446. <p>You can leave the data type as <code>string</code>, but compute an array to return. It won&#8217;t throw an error, but it will treat it like a single string.</p>
  447. <h4>No Data Type</h4>
  448. <p>You can remove the data type from the property definition and it won&#8217;t throw an error on the custom control. However, that is not a valid property, so its treated as though that property doesn&#8217;t exist.</p>
  449. <p>If you&#8217;ve already set up an instance of the custom control and passed a value to it, it will throw an error on the custom control instance: <em>Unknown property this.. It is not defined on tag .</em></p>
  450. <p><a href="https://xcellerant.files.wordpress.com/2016/04/custom-property-error-no-property-type-defined.png" rel="attachment wp-att-2846"><img loading="lazy" data-attachment-id="2846" data-permalink="https://xcellerant.wordpress.com/2016/04/12/xpages-tip-passing-an-array-to-a-custom-control-property/custom-property-error-no-property-type-defined/" data-orig-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-error-no-property-type-defined.png" data-orig-size="964,277" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Custom Property &#8211; Error &#8211; No Property Type Defined" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-error-no-property-type-defined.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-error-no-property-type-defined.png?w=519" class="aligncenter wp-image-2846 size-large" src="https://xcellerant.files.wordpress.com/2016/04/custom-property-error-no-property-type-defined.png?w=519&#038;h=149" alt="Custom Property - Error - No Property Type Defined"   srcset="https://xcellerant.files.wordpress.com/2016/04/custom-property-error-no-property-type-defined.png?w=800 800w, https://xcellerant.files.wordpress.com/2016/04/custom-property-error-no-property-type-defined.png?w=150 150w, https://xcellerant.files.wordpress.com/2016/04/custom-property-error-no-property-type-defined.png?w=300 300w, https://xcellerant.files.wordpress.com/2016/04/custom-property-error-no-property-type-defined.png?w=768 768w, https://xcellerant.files.wordpress.com/2016/04/custom-property-error-no-property-type-defined.png 964w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
  451. <h4>Custom Data Type</h4>
  452. <p>Fortunately, there&#8217;s a really simple solution &#8212; you can manually type in a property type.</p>
  453. <p>If you type in <code>object </code>as the type, it does the trick. (It effectively works as desired, although it actually accepts the data as <code>java.util.Vector</code>.)</p>
  454. <p><a href="https://xcellerant.files.wordpress.com/2016/04/custom-property-object-type.png" rel="attachment wp-att-2844"><img loading="lazy" data-attachment-id="2844" data-permalink="https://xcellerant.wordpress.com/2016/04/12/xpages-tip-passing-an-array-to-a-custom-control-property/custom-property-object-type/" data-orig-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-object-type.png" data-orig-size="489,301" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Custom Property &#8211; Object Type" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-object-type.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/04/custom-property-object-type.png?w=489" class="aligncenter wp-image-2844 size-full" src="https://xcellerant.files.wordpress.com/2016/04/custom-property-object-type.png?w=519" alt="Custom Property - Object Type"   srcset="https://xcellerant.files.wordpress.com/2016/04/custom-property-object-type.png 489w, https://xcellerant.files.wordpress.com/2016/04/custom-property-object-type.png?w=150&amp;h=92 150w, https://xcellerant.files.wordpress.com/2016/04/custom-property-object-type.png?w=300&amp;h=185 300w" sizes="(max-width: 489px) 100vw, 489px" /></a></p>
  455. ]]></content:encoded>
  456. <wfw:commentRss>https://xcellerant.wordpress.com/2016/04/12/xpages-tip-passing-an-array-to-a-custom-control-property/feed/</wfw:commentRss>
  457. <slash:comments>2</slash:comments>
  458. <media:content url="https://0.gravatar.com/avatar/fca56da31ba95401a45ec98668f0147f8f3d11756eb88c1d5ed3395c2c661f93?s=96&#38;d=identicon&#38;r=G" medium="image">
  459. <media:title type="html">xcellerant</media:title>
  460. </media:content>
  461.  
  462. <media:content url="https://xcellerant.files.wordpress.com/2016/04/custom-property-primitive-types.png" medium="image">
  463. <media:title type="html">Custom Property - Primitive Types</media:title>
  464. </media:content>
  465.  
  466. <media:content url="https://xcellerant.files.wordpress.com/2016/04/custom-property-property-types.png" medium="image">
  467. <media:title type="html">Custom Property - Property Types</media:title>
  468. </media:content>
  469.  
  470. <media:content url="https://xcellerant.files.wordpress.com/2016/04/custom-property-1-custom-property.png" medium="image">
  471. <media:title type="html">Custom Property - 1 Custom Property</media:title>
  472. </media:content>
  473.  
  474. <media:content url="https://xcellerant.files.wordpress.com/2016/04/custom-property-error-no-property-type-defined.png?w=800" medium="image">
  475. <media:title type="html">Custom Property - Error - No Property Type Defined</media:title>
  476. </media:content>
  477.  
  478. <media:content url="https://xcellerant.files.wordpress.com/2016/04/custom-property-object-type.png" medium="image">
  479. <media:title type="html">Custom Property - Object Type</media:title>
  480. </media:content>
  481. </item>
  482. <item>
  483. <title>XPages Tip: Beware Server-Side code in Multiple onClientLoad Events</title>
  484. <link>https://xcellerant.wordpress.com/2016/04/07/xpages-tip-beware-server-side-code-in-multiple-onclientload-events/</link>
  485. <comments>https://xcellerant.wordpress.com/2016/04/07/xpages-tip-beware-server-side-code-in-multiple-onclientload-events/#comments</comments>
  486. <dc:creator><![CDATA[Brad Balassaitis]]></dc:creator>
  487. <pubDate>Thu, 07 Apr 2016 10:06:12 +0000</pubDate>
  488. <category><![CDATA[JavaScript]]></category>
  489. <category><![CDATA[SSJS]]></category>
  490. <category><![CDATA[XPages]]></category>
  491. <category><![CDATA[XPages Tip]]></category>
  492. <category><![CDATA[PSC]]></category>
  493. <guid isPermaLink="false">http://xcellerant.net/?p=2838</guid>
  494.  
  495. <description><![CDATA[TL;DR &#8211; Server-side code in onClientLoad causes a page refresh and prevents additional onClientLoad events with server-side code from running. In this post, I&#8217;ll show an example and describe how it behaves. Page Ready Events It is extremely useful to have an event trigger that executes when the page is fully loaded; many JavaScript plugins [&#8230;]]]></description>
  496. <content:encoded><![CDATA[<p>TL;DR &#8211; Server-side code in onClientLoad causes a page refresh and prevents additional onClientLoad events with server-side code from running. In this post, I&#8217;ll show an example and describe how it behaves.</p>
  497. <h4>Page Ready Events</h4>
  498. <p>It is extremely useful to have an event trigger that executes when the page is fully loaded; many JavaScript plugins wait for the page to finish loading and then run to activate widgets on the page. Because of its importance, jQuery has <code>$(document).ready()</code> and Dojo has <code>dojo/domReady</code> and <code>dojo.addOnLoad()</code> to make this checking easy.</p>
  499. <h4>The Problem with onClientLoad in XPages</h4>
  500. <p>XPages provides the <code>onClientLoad </code>event on pages, custom controls, and panels. XPages allows you to run client-side and/or server-side code in the event. However, running server-side code can cause a tough-to-troubleshoot side effect.</p>
  501. <p>Take, for example, this XPage, which has two panels. Both panels and the page itself have client-side and server-side <code>onClientLoad </code>code to write a message to the browser console and server console, respectively.</p>
  502. <pre class="brush: plain; title: ; notranslate">
  503. &lt;?xml version=&quot;1.0&quot; encoding=&quot;UTF-8&quot;?&gt;
  504. &lt;xp:view xmlns:xp=&quot;http://www.ibm.com/xsp/core&quot;&gt;
  505.  
  506.  onClientLoad Event Testing
  507.  
  508.  &lt;xp:eventHandler event=&quot;onClientLoad&quot; submit=&quot;true&quot; refreshMode=&quot;norefresh&quot;&gt;
  509.    &lt;xp:this.script&gt;&lt;![CDATA[console.log('Page - onClientLoad');]]&gt;&lt;/xp:this.script&gt;
  510.    &lt;xp:this.action&gt;&lt;![CDATA[#{javascript:print('Page - onClientLoad');}]]&gt;&lt;/xp:this.action&gt;
  511.  &lt;/xp:eventHandler&gt;
  512.  
  513.  &lt;xp:panel id=&quot;panel1&quot;&gt;
  514.    &lt;xp:eventHandler event=&quot;onClientLoad&quot; submit=&quot;true&quot; refreshMode=&quot;norefresh&quot;&gt;
  515.      &lt;xp:this.script&gt;&lt;![CDATA[console.log('Panel 1 - onClientLoad');]]&gt;&lt;/xp:this.script&gt;
  516.      &lt;xp:this.action&gt;&lt;![CDATA[#{javascript:print('Panel 1 - onClientLoad');}]]&gt;&lt;/xp:this.action&gt;
  517.    &lt;/xp:eventHandler&gt;
  518.  &lt;/xp:panel&gt;
  519.  
  520.  &lt;xp:panel id=&quot;panel2&quot;&gt;
  521.    &lt;xp:eventHandler event=&quot;onClientLoad&quot; submit=&quot;true&quot; refreshMode=&quot;norefresh&quot;&gt;
  522.      &lt;xp:this.script&gt;&lt;![CDATA[console.log('Panel 2 - onClientLoad');]]&gt;&lt;/xp:this.script&gt;
  523.      &lt;xp:this.action&gt;&lt;![CDATA[#{javascript:print('Panel 2 - onClientLoad');}]]&gt;&lt;/xp:this.action&gt;
  524.    &lt;/xp:eventHandler&gt;
  525.  &lt;/xp:panel&gt;
  526.  
  527. &lt;/xp:view&gt;
  528. </pre>
  529. <p>Here&#8217;s what happens when the page loads:</p>
  530. <ol>
  531. <li>The page-level client-side code runs to write the message to the browser console</li>
  532. <li>The page-level server-side code runs to write the message to the server console</li>
  533. </ol>
  534. <p>That&#8217;s it. </p>
  535. <p><strong>Execution on <code>onClientLoad </code>handlers stops at this point because the page has posted to the server because of the server-side code; the <code>onClientLoad </code>event handlers for the panels do not execute at all.</strong></p>
  536. <p>You can look in the browser&#8217;s developer tools and see the POST that is sent. It doesn&#8217;t try to update anything on the page, so there&#8217;s no response, but it&#8217;s still enough to interrupt everything else.</p>
  537. <p>More details on the behavior:</p>
  538. <ul>
  539. <li>You can run multiple client-side <code>onClientLoad </code>event scripts without issue &#8212; as long as they&#8217;re not triggering partial refreshes</li>
  540. <li>If the event handlers are rearranged on the page, the one that comes first in the source is the one that will run</li>
  541. <li>If there is only one <code>onClientLoad </code>event with server-side code, it will run (based on it&#8217;s order in the source), then POST, then let the rest of the <code>onClientLoad </code>events on the page <em>that only have client-side code</em> run. (Any with server-side code will not execute &#8212; even the client-side event code on handlers that also have server-side code will not run.)</li>
  542. </ul>
  543. <h4>Mitigating the Problem</h4>
  544. <p>This may sound like an easy thing to keep in check, but if you have <code>onClientLoad </code>code on multiple custom controls, it may be hard to make sure that there won&#8217;t be a conflict, especially because there won&#8217;t be any error thrown.</p>
  545. <p>The strong recommendation is to just not put server-side code in the <code>onClientLoad </code>event, period.</p>
  546. <p>If you absolutely need it, then you may need a standard of putting any necessary <code>onClientLoad </code>code in the common layout control that&#8217;s loaded on every page, but it still has the potential to interrupt anything else going on the page or annoy the user by causing a delay immediately after the page is loaded waiting for the post and response. I would try to put code in the <code>afterPageLoad </code>event or use client-side code to trigger an RPC method or custom REST service if server-side code needs to run in that event.</p>
  547. ]]></content:encoded>
  548. <wfw:commentRss>https://xcellerant.wordpress.com/2016/04/07/xpages-tip-beware-server-side-code-in-multiple-onclientload-events/feed/</wfw:commentRss>
  549. <slash:comments>1</slash:comments>
  550. <media:content url="https://0.gravatar.com/avatar/fca56da31ba95401a45ec98668f0147f8f3d11756eb88c1d5ed3395c2c661f93?s=96&#38;d=identicon&#38;r=G" medium="image">
  551. <media:title type="html">xcellerant</media:title>
  552. </media:content>
  553. </item>
  554. <item>
  555. <title>getFragment() Doesn&#8217;t</title>
  556. <link>https://xcellerant.wordpress.com/2016/03/24/getfragment-doesnt/</link>
  557. <comments>https://xcellerant.wordpress.com/2016/03/24/getfragment-doesnt/#respond</comments>
  558. <dc:creator><![CDATA[Brad Balassaitis]]></dc:creator>
  559. <pubDate>Thu, 24 Mar 2016 11:07:38 +0000</pubDate>
  560. <category><![CDATA[XPages]]></category>
  561. <category><![CDATA[XPages Tip]]></category>
  562. <category><![CDATA[XSPUrl]]></category>
  563. <guid isPermaLink="false">http://xcellerant.net/?p=2815</guid>
  564.  
  565. <description><![CDATA[The XSPUrl object that you can access via the XPages context has a lot of handy methods. getFragement() isn&#8217;t one of them. I was looking through the help documentation for XSPUrl recently and noticed that the object includes a method for getting the url fragment (i.e. the part of the URL after the hash). It [&#8230;]]]></description>
  566. <content:encoded><![CDATA[<p>The XSPUrl object that you can access via the XPages <code>context</code> has a lot of handy methods. <code>getFragement()</code> isn&#8217;t one of them.</p>
  567. <p>I was looking through the help documentation for XSPUrl recently and noticed that the object includes a method for getting the url fragment (i.e. the part of the URL after the hash). It was unexpected, but I figured it could be handy since I was working with some (non-XPages) tabs on pages in a recent application.</p>
  568. <p>However, as shown on Dave Leedy&#8217;s helpful <a href="http://xpagescheatsheet.com/cheatsheet.nsf/url.xsp">XPages URL Cheatsheet</a>, <code>getFragment()</code> doesn&#8217;t return anything when referring to the URL gleaned from the current context!</p>
  569. <p>This makes sense, as the hash is a client-side redirect and is not even sent to the server, so a server-side method wouldn&#8217;t be able to see it. But it&#8217;s included in the <a href="http://www.ibm.com/support/knowledgecenter/SSVRGU_9.0.1/com.ibm.designer.domino.api.doc/r_wpdr_xsp_xspurl_getfragment_r.html?cp=SSVRGU_9.0.1">XPages Documentation</a> which, hilariously, references <a href="http://www.dominoguru.com/pages/xspurl_full_url_xpages_85.html">Chris Toohey&#8217;s post</a> about this from several years ago.</p>
  570. <p>Fortunately, if you need to work with the hash, you can use client-side Javascript&#8217;s <a href="http://www.w3schools.com/jsref/prop_loc_hash.asp">location.hash</a> property and pass it to server-side code as needed.</p>
  571. ]]></content:encoded>
  572. <wfw:commentRss>https://xcellerant.wordpress.com/2016/03/24/getfragment-doesnt/feed/</wfw:commentRss>
  573. <slash:comments>0</slash:comments>
  574. <media:content url="https://0.gravatar.com/avatar/fca56da31ba95401a45ec98668f0147f8f3d11756eb88c1d5ed3395c2c661f93?s=96&#38;d=identicon&#38;r=G" medium="image">
  575. <media:title type="html">xcellerant</media:title>
  576. </media:content>
  577. </item>
  578. <item>
  579. <title>Transferring a Bitbucket Repository</title>
  580. <link>https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/</link>
  581. <comments>https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/#respond</comments>
  582. <dc:creator><![CDATA[Brad Balassaitis]]></dc:creator>
  583. <pubDate>Tue, 22 Mar 2016 11:07:18 +0000</pubDate>
  584. <category><![CDATA[Bitbucket]]></category>
  585. <category><![CDATA[Source Control]]></category>
  586. <category><![CDATA[SourceTree]]></category>
  587. <category><![CDATA[XPages]]></category>
  588. <category><![CDATA[PSC]]></category>
  589. <guid isPermaLink="false">http://xcellerant.net/?p=2821</guid>
  590.  
  591. <description><![CDATA[I recently needed to move control of a source control repository on Bitbucket from a personal account to a company account. Fortunately, there&#8217;s a relatively easy built-in process to transfer it between accounts. In this post, I&#8217;ll show how it&#8217;s done. Open the repository in Bitbucket Click on Settings at the bottom of the left [&#8230;]]]></description>
  592. <content:encoded><![CDATA[<p>I recently needed to move control of a source control repository on Bitbucket from a personal account to a company account. Fortunately, there&#8217;s a relatively easy built-in process to transfer it between accounts. In this post, I&#8217;ll show how it&#8217;s done.</p>
  593. <ol>
  594. <li>Open the repository in Bitbucket</li>
  595. <li>Click on Settings at the bottom of the left navigation</li>
  596. <p><a href="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket1.jpg" rel="attachment wp-att-2829"><img loading="lazy" data-attachment-id="2829" data-permalink="https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/transferbitbucket1/" data-orig-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket1.jpg" data-orig-size="210,750" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TransferBitbucket1" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket1.jpg?w=84" data-large-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket1.jpg?w=210" class="aligncenter wp-image-2829" src="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket1.jpg?w=112&#038;h=400" alt="TransferBitbucket1" width="112" height="400" srcset="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket1.jpg?w=112&amp;h=400 112w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket1.jpg?w=42&amp;h=150 42w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket1.jpg 210w" sizes="(max-width: 112px) 100vw, 112px" /></a></p>
  597. <li>Click on Transfer repository under General</li>
  598. <p><a href="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket2.png" rel="attachment wp-att-2832"><img loading="lazy" data-attachment-id="2832" data-permalink="https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/transferbitbucket2/" data-orig-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket2.png" data-orig-size="291,497" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TransferBitbucket2" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket2.png?w=176" data-large-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket2.png?w=291" class="aligncenter wp-image-2832 size-medium" src="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket2.png?w=176&#038;h=300" alt="TransferBitbucket2" width="176" height="300" srcset="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket2.png?w=176 176w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket2.png?w=88 88w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket2.png 291w" sizes="(max-width: 176px) 100vw, 176px" /></a></p>
  599. <li>Choose the new owner and click the Transfer Ownership button</li>
  600. <p><a href="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket3.png" rel="attachment wp-att-2831"><img loading="lazy" data-attachment-id="2831" data-permalink="https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/transferbitbucket3/" data-orig-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket3.png" data-orig-size="1022,333" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TransferBitbucket3" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket3.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket3.png?w=519" class="aligncenter wp-image-2831" src="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket3.png?w=598&#038;h=195" alt="TransferBitbucket3" width="598" height="195" srcset="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket3.png?w=598 598w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket3.png?w=150 150w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket3.png?w=300 300w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket3.png?w=768 768w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket3.png 1022w" sizes="(max-width: 598px) 100vw, 598px" /></a></p>
  601. <li>Login to Bitbucket as with the account of the new owner</li>
  602. <li>Click on the user icon in the upper right and select “Inbox”</li>
  603. <p><a href="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket4.png" rel="attachment wp-att-2830"><img loading="lazy" data-attachment-id="2830" data-permalink="https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/transferbitbucket4/" data-orig-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket4.png" data-orig-size="338,264" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TransferBitbucket4" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket4.png?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket4.png?w=338" class="aligncenter wp-image-2830" src="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket4.png?w=200&#038;h=156" alt="TransferBitbucket4" width="200" height="156" srcset="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket4.png?w=150 150w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket4.png?w=200 200w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket4.png?w=300 300w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket4.png 338w" sizes="(max-width: 200px) 100vw, 200px" /></a></p>
  604. <li>You’ll see a message with the transfer request. (It will also be e-mailed to the account owner.)</li>
  605. <p><a href="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket5.jpg" rel="attachment wp-att-2828"><img loading="lazy" data-attachment-id="2828" data-permalink="https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/transferbitbucket5/" data-orig-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket5.jpg" data-orig-size="1180,140" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TransferBitbucket5" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket5.jpg?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket5.jpg?w=519" class="aligncenter wp-image-2828 size-large" src="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket5.jpg?w=519&#038;h=62" alt="TransferBitbucket5"   srcset="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket5.jpg?w=800 800w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket5.jpg?w=150 150w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket5.jpg?w=300 300w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket5.jpg?w=768 768w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket5.jpg?w=1024 1024w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket5.jpg 1180w" sizes="(max-width: 800px) 100vw, 800px" /></a></p>
  606. <li>Open the message and click the link that it contains</li>
  607. <p><a href="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket6.jpg" rel="attachment wp-att-2825"><img loading="lazy" data-attachment-id="2825" data-permalink="https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/transferbitbucket6/" data-orig-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket6.jpg" data-orig-size="1030,300" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TransferBitbucket6" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket6.jpg?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket6.jpg?w=519" class="aligncenter wp-image-2825" src="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket6.jpg?w=601&#038;h=175" alt="TransferBitbucket6" width="601" height="175" srcset="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket6.jpg?w=601 601w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket6.jpg?w=150 150w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket6.jpg?w=300 300w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket6.jpg?w=768 768w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket6.jpg?w=1024 1024w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket6.jpg 1030w" sizes="(max-width: 601px) 100vw, 601px" /></a></p>
  608. <li>Click the Accept button to transfer the repository</li>
  609. <p><a href="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket7.jpg" rel="attachment wp-att-2824"><img loading="lazy" data-attachment-id="2824" data-permalink="https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/transferbitbucket7/" data-orig-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket7.jpg" data-orig-size="750,350" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TransferBitbucket7" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket7.jpg?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket7.jpg?w=519" class="aligncenter wp-image-2824" src="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket7.jpg?w=450&#038;h=210" alt="TransferBitbucket7" width="450" height="210" srcset="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket7.jpg?w=450&amp;h=210 450w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket7.jpg?w=150&amp;h=70 150w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket7.jpg?w=300&amp;h=140 300w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket7.jpg 750w" sizes="(max-width: 450px) 100vw, 450px" /></a></p>
  610. <li>Now that the repository has been transferred, it takes you to the Access management screen so you can add users to the repository as needed.</li>
  611. <li>If anyone already had Source Tree set up to use the repository, they will need to update the repository settings to point to the new location.
  612. <ul>
  613. <li>If you try to commit to the original repo url, you get a 404 error when trying to push:</li>
  614. <p><a href="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket8.jpg" rel="attachment wp-att-2827"><img loading="lazy" data-attachment-id="2827" data-permalink="https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/transferbitbucket8/" data-orig-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket8.jpg" data-orig-size="600,300" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TransferBitbucket8" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket8.jpg?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket8.jpg?w=519" class="aligncenter wp-image-2827 size-medium" src="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket8.jpg?w=300&#038;h=150" alt="TransferBitbucket8" width="300" height="150" srcset="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket8.jpg?w=300 300w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket8.jpg 600w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket8.jpg?w=150 150w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
  615. <li>Open the repository in Source Tree</li>
  616. <li>Click on the Settings button in the upper right hand corner (or select Repository &gt; Repository Settings)</li>
  617. <li>Click on the default repository to select it</li>
  618. <p><a href="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket11.jpg" rel="attachment wp-att-2826"><img loading="lazy" data-attachment-id="2826" data-permalink="https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/transferbitbucket11/" data-orig-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket11.jpg" data-orig-size="750,400" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TransferBitbucket11" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket11.jpg?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket11.jpg?w=519" class="aligncenter size-medium wp-image-2826" src="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket11.jpg?w=300&#038;h=160" alt="TransferBitbucket11" width="300" height="160" srcset="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket11.jpg?w=300 300w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket11.jpg?w=600 600w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket11.jpg?w=150 150w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
  619. <li>Click the Edit button</li>
  620. <li>Update the URL to replace the previous Bitbucket account name to the new one in two places in the URL</li>
  621. <p><a href="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket12.jpg" rel="attachment wp-att-2823"><img loading="lazy" data-attachment-id="2823" data-permalink="https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/transferbitbucket12/" data-orig-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket12.jpg" data-orig-size="750,430" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TransferBitbucket12" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket12.jpg?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket12.jpg?w=519" class="aligncenter size-medium wp-image-2823" src="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket12.jpg?w=300&#038;h=172" alt="TransferBitbucket12" width="300" height="172" srcset="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket12.jpg?w=300 300w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket12.jpg?w=600 600w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket12.jpg?w=150 150w" sizes="(max-width: 300px) 100vw, 300px" /></a></p>
  622. <p><a href="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket13.jpg" rel="attachment wp-att-2822"><img loading="lazy" data-attachment-id="2822" data-permalink="https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/transferbitbucket13/" data-orig-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket13.jpg" data-orig-size="750,400" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="TransferBitbucket13" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket13.jpg?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket13.jpg?w=519" class="aligncenter size-medium wp-image-2822" src="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket13.jpg?w=300&#038;h=160" alt="TransferBitbucket13" width="300" height="160" srcset="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket13.jpg?w=300 300w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket13.jpg?w=600 600w, https://xcellerant.files.wordpress.com/2016/03/transferbitbucket13.jpg?w=150 150w" sizes="(max-width: 300px) 100vw, 300px" /></a></li>
  623. </ul>
  624. </li>
  625. </ol>
  626. ]]></content:encoded>
  627. <wfw:commentRss>https://xcellerant.wordpress.com/2016/03/22/transferring-a-bitbucket-repository/feed/</wfw:commentRss>
  628. <slash:comments>0</slash:comments>
  629. <media:content url="https://0.gravatar.com/avatar/fca56da31ba95401a45ec98668f0147f8f3d11756eb88c1d5ed3395c2c661f93?s=96&#38;d=identicon&#38;r=G" medium="image">
  630. <media:title type="html">xcellerant</media:title>
  631. </media:content>
  632.  
  633. <media:content url="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket1.jpg" medium="image">
  634. <media:title type="html">TransferBitbucket1</media:title>
  635. </media:content>
  636.  
  637. <media:content url="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket2.png?w=176" medium="image">
  638. <media:title type="html">TransferBitbucket2</media:title>
  639. </media:content>
  640.  
  641. <media:content url="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket3.png?w=800" medium="image">
  642. <media:title type="html">TransferBitbucket3</media:title>
  643. </media:content>
  644.  
  645. <media:content url="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket4.png?w=150" medium="image">
  646. <media:title type="html">TransferBitbucket4</media:title>
  647. </media:content>
  648.  
  649. <media:content url="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket5.jpg?w=800" medium="image">
  650. <media:title type="html">TransferBitbucket5</media:title>
  651. </media:content>
  652.  
  653. <media:content url="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket6.jpg?w=800" medium="image">
  654. <media:title type="html">TransferBitbucket6</media:title>
  655. </media:content>
  656.  
  657. <media:content url="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket7.jpg" medium="image">
  658. <media:title type="html">TransferBitbucket7</media:title>
  659. </media:content>
  660.  
  661. <media:content url="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket8.jpg?w=300" medium="image">
  662. <media:title type="html">TransferBitbucket8</media:title>
  663. </media:content>
  664.  
  665. <media:content url="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket11.jpg?w=300" medium="image">
  666. <media:title type="html">TransferBitbucket11</media:title>
  667. </media:content>
  668.  
  669. <media:content url="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket12.jpg?w=300" medium="image">
  670. <media:title type="html">TransferBitbucket12</media:title>
  671. </media:content>
  672.  
  673. <media:content url="https://xcellerant.files.wordpress.com/2016/03/transferbitbucket13.jpg?w=300" medium="image">
  674. <media:title type="html">TransferBitbucket13</media:title>
  675. </media:content>
  676. </item>
  677. <item>
  678. <title>Handling Errors in an XPages RPC Method</title>
  679. <link>https://xcellerant.wordpress.com/2016/02/17/handling-errors-in-an-xpages-rpc-method/</link>
  680. <comments>https://xcellerant.wordpress.com/2016/02/17/handling-errors-in-an-xpages-rpc-method/#comments</comments>
  681. <dc:creator><![CDATA[Brad Balassaitis]]></dc:creator>
  682. <pubDate>Wed, 17 Feb 2016 12:07:26 +0000</pubDate>
  683. <category><![CDATA[JavaScript]]></category>
  684. <category><![CDATA[JSON RPC]]></category>
  685. <category><![CDATA[SSJS]]></category>
  686. <category><![CDATA[Uncategorized]]></category>
  687. <category><![CDATA[XPages]]></category>
  688. <guid isPermaLink="false">http://xcellerant.net/?p=2770</guid>
  689.  
  690. <description><![CDATA[The Remote Service (aka xe:jsonRPCService) is an extremely useful control in XPages because it examples client- and server-side code interaction, runs asynchronously, performs well, and is easy to use. But if you don&#8217;t handle errors well, it can fail quietly and the user may never know. In this post, I&#8217;ll show how to handle client- [&#8230;]]]></description>
  691. <content:encoded><![CDATA[<p>The Remote Service (aka xe:jsonRPCService) is an extremely useful control in XPages because it examples client- and server-side code interaction, runs asynchronously, performs well, and is easy to use. But if you don&#8217;t handle errors well, it can fail quietly and the user may never know. In this post, I&#8217;ll show how to handle client- and server-side JavaScript errors with an RPC method.</p>
  692. <h4>Remote Procecure Example</h4>
  693. <p>As a starting point, let&#8217;s look at an example of a simple RPC method that returns the date and time and displays it for the user.</p>
  694. <h5>RPC Control</h5>
  695. <p>Here&#8217;s the XPages component source:</p>
  696. <pre class="brush: plain; title: ; notranslate">
  697. &lt;xe:jsonRpcService id=&quot;jsonRpcService1&quot; serviceName=&quot;myRPCService&quot;&gt;
  698.  &lt;xe:this.methods&gt;
  699.    &lt;xe:remoteMethod name=&quot;myMethod&quot; script=&quot;return myLibraryFunction();&quot;&gt;
  700.    &lt;/xe:remoteMethod&gt;
  701.  &lt;/xe:this.methods&gt;
  702. &lt;/xe:jsonRpcService&gt;
  703. </pre>
  704. <p>The service name is <strong>myRPCService</strong>. The method, <strong>myMethod</strong> takes no parameters and just calls an SSJS library function named <strong>myLibraryFunction()</strong>.</p>
  705. <h5>SSJS Library Function</h5>
  706. <p>Here&#8217;s the SSJS function that it calls:</p>
  707. <pre class="brush: plain; title: ; notranslate">
  708. function myLibraryFunction() {
  709.  var d = new Date();
  710.  return d.toLocaleString();
  711. }
  712. </pre>
  713. <h5>Client-Side JavaScript</h5>
  714. <p>Here&#8217;s the code that calls the RPC method:</p>
  715. <pre class="brush: plain; title: ; notranslate">
  716. myRPCService.myMethod().addCallback(function (response) {
  717.  alert('response: ' + response);
  718. })
  719. </pre>
  720. <p>It calls the method in the RPC service and attaches a callback function to wait for the response. It then displays the response to the user in an alert.</p>
  721. <p><img loading="lazy" data-attachment-id="2796" data-permalink="https://xcellerant.wordpress.com/2016/02/17/handling-errors-in-an-xpages-rpc-method/rpc-error-handling-a/" data-orig-file="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-a.gif" data-orig-size="419,185" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="RPC Error Handling &#8211; A" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-a.gif?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-a.gif?w=419" class="aligncenter size-full wp-image-2796" src="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-a.gif?w=519" alt="RPC Error Handling - A"   srcset="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-a.gif 419w, https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-a.gif?w=150&amp;h=66 150w, https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-a.gif?w=300&amp;h=132 300w" sizes="(max-width: 419px) 100vw, 419px" /></p>
  722. <h4>Handling Client-Side Errors</h4>
  723. <p>This works well and RPC functionality is awesome, but you have to be careful about how you handle errors.</p>
  724. <p>Take for example, this problematic update. This code ignores the response, but tries to display an invalid value (an undeclared variable) in an alert.</p>
  725. <pre class="brush: plain; title: ; notranslate">
  726. myRPCService.myMethod().addCallback(function (response) {
  727.  console.log('before');
  728.  alert ('Invalid variable: ' + myUndeclaredVariable);
  729.  console.log('after');
  730. })
  731. </pre>
  732. <p>When you run the code, it appears that nothing happens. The console shows the &#8216;before&#8217; statement, but it then fails quietly.</p>
  733. <p>Putting a try-catch block around it like this doesn&#8217;t help at all.</p>
  734. <pre class="brush: plain; title: ; notranslate">
  735. try {
  736.  myRPCService.myMethod().addCallback(function (response) {
  737.    console.log('before');
  738.    alert ('Invalid variable: ' + myUndeclaredVariable);
  739.    console.log('after');
  740.  })
  741. } catch (e) {
  742. alert('Error: ' + e.toString());
  743. }
  744. </pre>
  745. <p>This may seem a bit confusing, but it actually makes sense. The callback effectively runs in its own scope, so <strong><em>the error handling needs to be within the callback</em></strong> in order to fire when dealing with an RPC call.</p>
  746. <p>This code does the trick:</p>
  747. <pre class="brush: plain; title: ; notranslate">
  748. myRPCService.myMethod().addCallback(function (response) {
  749.  try {
  750.    console.log('before');
  751.    alert ('Invalid variable: ' + myUndeclaredVariable);
  752.    console.log('after');
  753.  } catch (e) {
  754.    alert('Error: ' + e.toString());
  755.  }
  756. })
  757. </pre>
  758. <p><img loading="lazy" data-attachment-id="2795" data-permalink="https://xcellerant.wordpress.com/2016/02/17/handling-errors-in-an-xpages-rpc-method/rpc-error-handling-b/" data-orig-file="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-b.gif" data-orig-size="437,181" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="RPC Error Handling &#8211; B" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-b.gif?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-b.gif?w=437" class="aligncenter size-full wp-image-2795" src="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-b.gif?w=519" alt="RPC Error Handling - B"   srcset="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-b.gif 437w, https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-b.gif?w=150&amp;h=62 150w, https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-b.gif?w=300&amp;h=124 300w" sizes="(max-width: 437px) 100vw, 437px" /></p>
  759. <h4>Handling Server-Side Errors</h4>
  760. <p>If there&#8217;s an unhandled exception on the server-side code that runs (such as an error or forgetting to return a response), it also fails quietly, although it will show a few errors in the browser console.</p>
  761. <p><img loading="lazy" data-attachment-id="2794" data-permalink="https://xcellerant.wordpress.com/2016/02/17/handling-errors-in-an-xpages-rpc-method/rpc-error-handling-c/" data-orig-file="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-c.gif" data-orig-size="1556,101" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="RPC Error Handling &#8211; C" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-c.gif?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-c.gif?w=519" class="alignnone size-full wp-image-2794" src="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-c.gif?w=519" alt="RPC Error Handling - C"   srcset="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-c.gif 1556w, https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-c.gif?w=150&amp;h=10 150w, https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-c.gif?w=300&amp;h=19 300w, https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-c.gif?w=768&amp;h=50 768w, https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-c.gif?w=1024&amp;h=66 1024w" sizes="(max-width: 1556px) 100vw, 1556px" /></p>
  762. <p>If you expand the POST, you&#8217;ll see that it returns a stack trace for an RPC error.</p>
  763. <p>In this case, error handling in the client-side callback function doesn&#8217;t help at all, so it&#8217;s important to handle the error in the server-side code and return something that the callback can deal with.</p>
  764. <pre class="brush: plain; title: ; notranslate">
  765. function myLibraryFunction() {
  766.  try {
  767.    print (myUndeclaredVariable);
  768.    var d = new Date();
  769.    return d.toLocaleString();
  770.  } catch (e) {
  771.    return 'Error: ' + e.toString();
  772.  }
  773. }
  774. </pre>
  775. <p><img loading="lazy" data-attachment-id="2793" data-permalink="https://xcellerant.wordpress.com/2016/02/17/handling-errors-in-an-xpages-rpc-method/rpc-error-handling-d/" data-orig-file="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-d.gif" data-orig-size="385,187" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="RPC Error Handling &#8211; D" data-image-description="" data-image-caption="" data-medium-file="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-d.gif?w=300" data-large-file="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-d.gif?w=385" class="aligncenter size-full wp-image-2793" src="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-d.gif?w=519" alt="RPC Error Handling - D"   srcset="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-d.gif 385w, https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-d.gif?w=150&amp;h=73 150w, https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-d.gif?w=300&amp;h=146 300w" sizes="(max-width: 385px) 100vw, 385px" /></p>
  776. <p>Now, I&#8217;m returning a more informative message to the user about what went wrong.</p>
  777. <p>I generally like to set up my server-side methods to return an object to the callback function, because that way I can add as many properties as I want in order to return all of the information that I need. I generally include a property for a boolean value for whether the method was successful and another value that contains a success or error message. In the callback, those values can be checked and appropriate action can be taken accordingly.</p>
  778. ]]></content:encoded>
  779. <wfw:commentRss>https://xcellerant.wordpress.com/2016/02/17/handling-errors-in-an-xpages-rpc-method/feed/</wfw:commentRss>
  780. <slash:comments>4</slash:comments>
  781. <media:content url="https://0.gravatar.com/avatar/fca56da31ba95401a45ec98668f0147f8f3d11756eb88c1d5ed3395c2c661f93?s=96&#38;d=identicon&#38;r=G" medium="image">
  782. <media:title type="html">xcellerant</media:title>
  783. </media:content>
  784.  
  785. <media:content url="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-a.gif" medium="image">
  786. <media:title type="html">RPC Error Handling - A</media:title>
  787. </media:content>
  788.  
  789. <media:content url="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-b.gif" medium="image">
  790. <media:title type="html">RPC Error Handling - B</media:title>
  791. </media:content>
  792.  
  793. <media:content url="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-c.gif" medium="image">
  794. <media:title type="html">RPC Error Handling - C</media:title>
  795. </media:content>
  796.  
  797. <media:content url="https://xcellerant.files.wordpress.com/2016/02/rpc-error-handling-d.gif" medium="image">
  798. <media:title type="html">RPC Error Handling - D</media:title>
  799. </media:content>
  800. </item>
  801. </channel>
  802. </rss>
  803.  

If you would like to create a banner that links to this page (i.e. this validation result), do the following:

  1. Download the "valid RSS" banner.

  2. Upload the image to your own server. (This step is important. Please do not link directly to the image on this server.)

  3. Add this HTML to your page (change the image src attribute if necessary):

If you would like to create a text link instead, here is the URL you can use:

http://www.feedvalidator.org/check.cgi?url=http%3A//xcellerant.wordpress.com/feed/

Copyright © 2002-9 Sam Ruby, Mark Pilgrim, Joseph Walton, and Phil Ringnalda