<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.9.2 (http://www.squarespace.com/) on Fri, 12 Mar 2010 21:35:16 GMT--><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"><title>The XPages Blog</title><subtitle>XPages Blog</subtitle><id>http://xpagesblog.com/xpages-blog/</id><link rel="alternate" type="application/xhtml+xml" href="http://xpagesblog.com/xpages-blog/"/><link rel="self" type="application/atom+xml" href="http://xpagesblog.com/xpages-blog/atom.xml"/><updated>2010-03-10T00:07:08Z</updated><generator uri="http://www.squarespace.com/" version="Squarespace Site Server v5.9.2 (http://www.squarespace.com/)">Squarespace</generator><entry><title>Follow The XPages Blog on Twitter</title><category term="Social Media"/><category term="twitter"/><id>http://xpagesblog.com/xpages-blog/2010/3/9/follow-the-xpages-blog-on-twitter.html</id><link rel="alternate" type="text/html" href="http://xpagesblog.com/xpages-blog/2010/3/9/follow-the-xpages-blog-on-twitter.html"/><author><name>Bruce Elgort</name></author><published>2010-03-10T00:04:49Z</published><updated>2010-03-10T00:04:49Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>The XPages Blog now has a Twitter account:</p>
<p><a href="http://twitter.com/xpagesblog">http://twitter.com/xpagesblog</a></p>
<p>Please follow us to get the latest and greatest XPages goodness from the industries leading XPages experts.</p>]]></content></entry><entry><title>Advanced HTML Element Select with Control and Shift Click</title><category term="Development"/><category term="Tips and Tricks"/><category term="UI"/><category term="dojo"/><category term="selectable"/><id>http://xpagesblog.com/xpages-blog/2010/3/9/advanced-html-element-select-with-control-and-shift-click.html</id><link rel="alternate" type="text/html" href="http://xpagesblog.com/xpages-blog/2010/3/9/advanced-html-element-select-with-control-and-shift-click.html"/><author><name>Jeremy Hodge</name></author><published>2010-03-09T22:48:20Z</published><updated>2010-03-09T22:48:20Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>In <a href="http://xpagesblog.com/xpages-blog/2010/3/7/quicktip-html-element-selection-using-dojo.html">my last post</a> I discussed how to use dojo and CSS classes to create a user-selectable set of HTML   elements. The example provided a list-like single-selection interface that allowed the user to only select single elements.</p>
<p>Today, I am going to expand upon that example to create a multiple-select interface allowing the user to control-click or shift-click to select multiple elements.</p>
<p>We are going to start off right where we left off last time, by modifying the focusObject() function we previously definded. The function is going to be a bit more involved as we need to check for 4 mouse   states (click, control click, shift click, and control shift click). Let's start the update by redefining the parameters to our function. If you remember, our previous function template was as follows</p>
<blockquote><code> function focusObject(class,objId) { } </code></blockquote>
<p>We're going to change this template to include a new parameter "e" which will be the first argument that the event handler in non-IE browsers receives, or for IE browsers, the event object. So, redefined,   our function template now looks like this:</p>
<blockquote><code> function focusObject(class,objId,e) { } </code></blockquote>
<p>The e parameter holds the two boolean properties ctrlKey and shiftKey which tells us the state of the keys at the time the click ocurred. Quite simply, if they are true, the appropriate key was pressed.   So, lets expand our function a litle bit, and create a statement that will check for each of the four conditions we need to check. Also, because we are going to refer to the HTML node the user selected quite   frequently, lets go ahead and capture that node to a variable right from the start.</p>
<blockquote><code> function focusObject(class,objId,e) {<br />&nbsp; // Capture the selected node...<br />&nbsp; var selNode = dojo.byId(objId);<br /><br />&nbsp; // JUST CLICK<br />&nbsp; if ((!e.ctrlKey) &amp;&amp; (!e.shiftKey)) {<br /><br />&nbsp; // CONTROL SHIFT CLICK<br />&nbsp; } else if ((e.ctrlKey) &amp;&amp; (e.shiftKey)) {<br /><br />&nbsp; // CONTROL CLICK<br />&nbsp; } else if (e.ctrlKey) {<br /><br />&nbsp; // SHIFT CLICK 	<br />&nbsp; } else if (e.shiftKey) {<br /><br />&nbsp; }<br /> } </code></blockquote>
<p>Ok, let's tackle the obvious first, just plain ol' click, which we defined yesterday. The same code we created then will work now, so lets go ahead and insert that. At the same time, we need to start to   not only track which items have been selected (with the CSS 'focused' class), but also which item was the last item the user clicked before the current one. This way we have a starting point, and an ending   point for the range of elements the user wants to select when they shift click. To do this, we are going to introduce a new CSS class called 'lastSelected'.  On every click we need to clear any item with the    lastSelected class, and set the currently clicked item as 'lastSelected'.  We want to do this after we have done all our processing so we know during shift-select what the last item was. So, at the end of   the function, we are going to add two lines almost identical to the focusObject function from the last post, but in addition to using the passed in class name, we are going to add the new .lastSelected class   as well.</p>
<blockquote>function focusObject(class,objId,e) {<br /><br />&nbsp;&nbsp; &nbsp;// Capture the selected node...<br />&nbsp;&nbsp; &nbsp;var selNode = dojo.byId(objId);<br /><br />&nbsp;&nbsp; &nbsp;// JUST CLICK<br />&nbsp;&nbsp; &nbsp;if ((!e.ctrlKey) &amp;&amp; (!e.shiftKey)) {<br />&nbsp;&nbsp; &nbsp;&nbsp; dojo.query(class+'.focused').removeClass('focused');<br />&nbsp;&nbsp; &nbsp;&nbsp; dojo.addClass(selNode, 'focused');<br />&nbsp;&nbsp; &nbsp;// CONTROL SHIFT CLICK<br />&nbsp;&nbsp; &nbsp;} else if ((e.ctrlKey) &amp;&amp; (e.shiftKey)) {<br /><br />&nbsp;&nbsp; &nbsp;// CONTROL CLICK<br />&nbsp;&nbsp; &nbsp;} else if (e.ctrlKey) {<br /><br />&nbsp;&nbsp; &nbsp;// SHIFT CLICK<br />&nbsp;&nbsp; &nbsp;} else if (e.shiftKey) {<br /><br />&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;// Update the last click item to the item the user clicked this time<br />&nbsp;&nbsp; &nbsp;dojo.query(class + '.lastSelected').removeClass('lastSelected');<br />&nbsp;&nbsp; &nbsp;dojo.addClass(selNode, 'lastSelected')<br />}</blockquote>
<p>Notice also how I have removed the calls to dojo.byId() and replaced them with selNode, since we have previously acquired it.</p>
<p>Now lets tackle the next easiest click, the control click. On a control-click the user is simply adding, or removing a previously selected item to the list. There is no need to clear the focused items. So   we just need to check to see if selNode already has the focused CSS class, and if so remove it, otherwise, we need to add it. Let's plug in that code now.</p>
<blockquote>function focusObject(class,objId,e) {<br /><br />&nbsp;&nbsp; &nbsp;// Capture the selected node...<br />&nbsp;&nbsp; &nbsp;var selNode = dojo.byId(objId);<br /><br />&nbsp;&nbsp; &nbsp;// JUST CLICK<br />&nbsp;&nbsp; &nbsp;if ((!e.ctrlKey) &amp;&amp; (!e.shiftKey)) {<br />&nbsp;&nbsp; &nbsp;&nbsp; dojo.query(class+'.focused').removeClass('focused');<br />&nbsp;&nbsp; &nbsp;&nbsp; dojo.addClass(selNode, 'focused');<br />&nbsp;&nbsp; &nbsp;// CONTROL SHIFT CLICK<br />&nbsp;&nbsp; &nbsp;} else if ((e.ctrlKey) &amp;&amp; (e.shiftKey)) {<br /><br />&nbsp;&nbsp; &nbsp;// CONTROL CLICK<br />&nbsp;&nbsp; &nbsp;} else if (e.ctrlKey) {<br />&nbsp;&nbsp; &nbsp;&nbsp; if (dojo.hasClass(selNode, 'focused'))<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; dojo.removeClass(selNode, 'focused')<br />&nbsp;&nbsp; &nbsp;&nbsp; else<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; dojo.addClass(selNode, 'focused');<br />&nbsp;&nbsp; &nbsp;// SHIFT CLICK<br />&nbsp;&nbsp; &nbsp;} else if (e.shiftKey) {<br /><br />&nbsp;&nbsp; &nbsp;}<br />&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp; &nbsp;// Update the last click item to the item the user clicked this time<br />&nbsp;&nbsp; &nbsp;dojo.query(class + '.lastSelected').removeClass('lastSelected');<br />&nbsp;&nbsp; &nbsp;dojo.addClass(selNode, 'lastSelected')<br />}</blockquote>
<p>Ok, now we start to get to the tricky parts. The Shifty clicks.  Two expected behaviors are expected here. First, if I Shift-Click, I would expect the only items selected to be the items between the   last item I selected and the one I select this time, inclusive, or if Control-Shift-Click, I would expect my selections to be logically AND'ed with my previous selections, using again the last item I   clicked, and the item clicked this time. Let's start with the Control-Shift-Click.</p>
<p>To accomplish the selection of items within a list of elements, we'll need to introduce a couple of new functions. Here's a run down of them real quick.</p>
<blockquote>
<p>dojo.indexOf() - Basically this takes an array in the first argument, and a single item in the second argument, and returns the index of the array in argument 1 where argument 2 appears. If no match is   found, it returns a -1.</p>
</blockquote>
<blockquote>
<p>HTMLNode.parentNode, HTMLNode.childNodes, HTMLNode.previousSibling, and HTML.nextSibling are all functions related to the relative traversal of HTML elements located in the DOM. parentNode returns an   element's parent, childNodes returns an array of an element's immediate children, previousSibling and nextSibling return the previous/next immediate html node that is a sibling to itself. This includes   whitespace nodes, text, etc, so we have to do a bit of type checking when using these functions.</p>
</blockquote>
<p>I chose to start the shifty clicks with the Control Shift Click because we don't have to worry about what has been selected before. We just need to find, and select then inclusive items between our two   elements. To do this, we first find the index of our two bounding nodes within our parent node. We do this with a combination of the parentNode, childNodes and dojo.indexOf functions. Here is the code:</p>
<blockquote><code> var idx = dojo.indexOf(selNode.parentNode.childNodes, selNode);<br />var lastIdx = dojo.indexOf(selNode.parentNode.childNodes, dojo.query(class+'.lastSelected')[0]); </code></blockquote>
<p>idx locates the index of the currently selected node in it's parent, and lastIdx locates the index of the last selected item within the currently selected node's parent. We check for the last selected   node in the current selected node's parent because this will allow us to have multiple lists on a single page, and would prevent us from selecting from one item in one list to another item in another list.   If the last selection is not in the same parent as the current, lastIdx will be -1 and we know we need to reset the selected items, and start a new selection.</p>
<p>Assuming we are in the same list, we compare idx and lastIdx to determine which direction we need to traverse from the currently selected node. If idx &gt; lastIdx, we use nextSibling, and if idx &lt; lastIdx,   we use previousSibling. In either case we just traverse from selNode to the last selected nodes, turning on focus for each node along the path that has the passed in class. This is where we need to check the   nodeType of each sibling node we retrieve to make sure it is an element that we want to select. You can <a href="http://www.w3schools.com/htmldom/dom_nodes_info.asp">read about nodeTypes here</a>, but   suffice it to say, we are looking for the Element node type, which is type 1. Here is the code to determine if the last two selected nodes are in the same parent, and if so determine the direction to   traverse, and then actually performs the selection.</p>
<blockquote>if (lastIdx == -1) {&nbsp; // the last selected was not in the same parent, so we can't shift click, so just reset the focused nodes and select the single node ...<br />&nbsp; dojo.query(class + '.focused').removeClass('focused');&nbsp;&nbsp; &nbsp; &nbsp;<br />&nbsp; dojo.addClass(selNode, 'focused');<br />} else {<br />&nbsp; if (idx &lt; lastIdx) {<br />&nbsp;&nbsp;&nbsp; var el = selNode;<br />&nbsp;&nbsp;&nbsp; for ( ; lastIdx &gt;= idx; idx++) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((el.nodeType == 1) &amp;&amp; (dojo.hasClass(el, class.split('.').join(''))))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.addClass(el, 'focused');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; el = el.nextSibling;<br />&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp; } else if (idx &gt; lastIdx) {<br />&nbsp;&nbsp;&nbsp; var el = selNode;<br />&nbsp;&nbsp;&nbsp; for ( ; lastIdx &lt;= idx; idx--) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((el.nodeType == 1) &amp;&amp; (dojo.hasClass(el, class.split('.').join(''))))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.addClass(el, 'focused');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; el = el.previousSibling;<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp; }&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br />}</blockquote>
<p>Now we can worry about the straight shift click. It operates just like control shift click except we need to clear any previously selected items first. Since that is the case, we can simplify our code by   removing the seperate check for the control shift click, and integrate the check for a non-control shift click into the same code as above. So, lets start by tweaking our original expanded function template   a bit, and add in some code during our shift click code to check for the control key. We'll make a check during the control shift click code we did above, and if they aren't holding down control, we'll clear   out all the current selections, re-select the last selected element, and perform the same selection operations as control-shift-click, and wallah, we have shift-click covered too.</p>
<blockquote>function focusObject(class,objId,e) {<br /><br />&nbsp; // Capture the selected node...<br />&nbsp; var selNode = dojo.byId(objId);<br /><br />&nbsp; // JUST CLICK<br />&nbsp; if ((!e.ctrlKey) &amp;&amp; (!e.shiftKey)) {<br /><br />&nbsp; // JUST CONTROL CLICK<br />&nbsp; } else if ((e.ctrlKey) &amp;&amp; (!e.shiftKey)) {<br /><br /><br />&nbsp; // SHIFTY CLICKS<br />&nbsp; } else if (e.shiftKey) {<br /><br />&nbsp;&nbsp;&nbsp; if (!e.ctrlKey) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // clear all previous selections first, re-add lastSelected, then process on<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.query(class + '.focused').removeClass('focused');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.query(class + '.lastSelected').addClass('focused');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.addClass(selection, 'focused');<br /><br />&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp; }<br />&nbsp;&nbsp; &nbsp;<br />}</blockquote>
<p>Now we can put it all together, and make one last simple adjustment. If the user shift clicks the same element twice, we need to just dump out of our routine since we shouldn't deselect anything, and the   last item is already selected. We'll do that right after we get idx and lastIdx, and if they equal each other, we'll just drop out.</p>
<p>So here it is, our final assembled function</p>
<blockquote>function focusObject(class,objId,e) {<br />&nbsp; var selNode = dojo.byId(objId);<br />&nbsp; if ((!e.ctrlKey) &amp;&amp; (!e.shiftKey)) {<br />&nbsp;&nbsp;&nbsp; dojo.query(class + '.focused').removeClass('focused');<br />&nbsp;&nbsp;&nbsp; dojo.addClass(selNode, 'focused');<br />&nbsp; } else if ((e.ctrlKey) &amp;&amp; (!e.shiftKey))<br />&nbsp;&nbsp;&nbsp; if (dojo.hasClass(selNode, 'focused'))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.removeClass(selNode, 'focused')<br />&nbsp;&nbsp;&nbsp; else<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.addClass(selNode, 'focused');<br />&nbsp; else if (e.shiftKey) {<br />&nbsp;&nbsp;&nbsp; var idx = dojo.indexOf(selNode.parentNode.childNodes, selNode);<br />&nbsp;&nbsp;&nbsp; var lastIdx = dojo.indexOf(selNode.parentNode.childNodes, dojo.query(class + '.lastSelected')[0])<br />&nbsp;&nbsp;&nbsp; if (idx == lastIdx) {<br />&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;return true; // user just shift clicked the same node again, don't do anything <br />&nbsp;&nbsp;&nbsp; }<br /><br />&nbsp;&nbsp;&nbsp; if (!e.ctrlKey) { <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; // clear all previous selections first, re-add lastSelected, then process on<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.query(class + '.focused').removeClass('focused');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.query(class + '.lastSelected').addClass('focused');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.addClass(selection, 'focused');<br />&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp; &nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp; if (lastIdx == -1) {&nbsp; // the last selected was not in the same parent, so we can't shift click, so just reset the focused nodes and select the single node ...<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.query(class + '.focused').removeClass('focused');&nbsp;&nbsp; &nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.addClass(selNode, 'focused');<br />&nbsp;&nbsp;&nbsp; } else {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (idx &lt; lastIdx) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var el = selNode;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( ; lastIdx &gt;= idx; idx++) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((el.nodeType == 1) &amp;&amp; (dojo.hasClass(el, class.split('.').join(''))))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.addClass(el, 'focused');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; el = el.nextSibling;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else if (idx &gt; lastIdx) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; var el = selNode;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( ; lastIdx &lt;= idx; idx--) {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((el.nodeType == 1) &amp;&amp; (dojo.hasClass(el, class.split('.').join(''))))<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dojo.addClass(el, 'focused');<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; el = el.previousSibling;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;<br />&nbsp;&nbsp;&nbsp; }&nbsp;&nbsp; &nbsp;<br />&nbsp; }<br />&nbsp;&nbsp; &nbsp;<br />&nbsp; dojo.query(class + '.lastSelected').removeClass('lastSelected');<br />&nbsp; dojo.addClass(selNode, 'lastSelected')<br />}</blockquote>
<p>Now, we are almost there, there are a few more things we need to take care of. First, as in the last post, we need to call focusObject() when our item gets clicked, but now, we have to get the event object and pass it in as well. So our event handler code from the last post for the element changes from this:</p>
<blockquote>
<p>&lt;xp:eventHandler event="onclick" submit="false"&gt;<br />&nbsp;  &lt;xp:this.script&gt;<br />&nbsp;&nbsp;&nbsp; &lt;![CDATA[<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  focusObject('.userSelectable', '#{id:REPLACEWITHOBJECTID}');<br />&nbsp;&nbsp;&nbsp;  ]]&gt;<br />&nbsp; &lt;/xp:this.script&gt;<br />&lt;/xp:eventHandler&gt;</p>
</blockquote>
<p>to this:</p>
<blockquote>
<p>&lt;xp:eventHandler event="onclick" submit="false"&gt;<br />&nbsp;  &lt;xp:this.script&gt;<br />&nbsp;&nbsp;&nbsp; &lt;![CDATA[<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;  focusObject('.userSelectable', '#{id:REPLACEWITHOBJECTID}', ((navigator.appName=="Netscape") ? arguments[0] : event));<br />&nbsp;&nbsp;&nbsp;  ]]&gt;<br />&nbsp; &lt;/xp:this.script&gt;<br />&lt;/xp:eventHandler&gt;</p>
</blockquote>
<p>And one last thing, the default browser behavior when you shift click within the body of the HTML page is to high-light the text of the page, of which the end result of all our work would rather hacky, like this:</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/shiftSelect.gif?__SQUARESPACE_CACHEVERSION=1268175869417" alt="" /></span></span></p>
<p>To prevent this, we'll use some javascript to disable the selection of text on the page.&nbsp; This disables selection of text on the entire document, which for my current use case, is fine, but I am fairly certain this can be adapted to specific elements as well, it is just untested at the moment.</p>
<p>To prevent the selection of text, at the beginning of your client-side javascript library, add the following code:</p>
<blockquote>
<p>function disableselect(e){ return false; }<br />function reEnable(){ return true; }<br /><br />document.onselectstart=new Function ("return false");<br /><br />if (window.sidebar){<br />&nbsp;&nbsp; &nbsp;document.onmousedown=disableselect;<br />&nbsp;&nbsp; &nbsp;document.onclick=reEnable;<br />}</p>
</blockquote>
<p>And you'll get a nice, clean shift-select:</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/shiftSelect2.gif?__SQUARESPACE_CACHEVERSION=1268176137685" alt="" /></span></span></p>
<p>Well, thats the book (quite literally it appears) on single and multple html element selection. In an upcoming post, I'll show you how to implement this as a practical application add-in along with identifying and working with the selected elements.</p>
<p>Happy Coding!</p>]]></content></entry><entry><title>QuickTip: HTML Element Selection Using Dojo</title><category term="Development"/><category term="Tips and Tricks"/><category term="UI"/><category term="dojo"/><category term="selectable"/><id>http://xpagesblog.com/xpages-blog/2010/3/7/quicktip-html-element-selection-using-dojo.html</id><link rel="alternate" type="text/html" href="http://xpagesblog.com/xpages-blog/2010/3/7/quicktip-html-element-selection-using-dojo.html"/><author><name>Jeremy Hodge</name></author><published>2010-03-07T14:29:13Z</published><updated>2010-03-07T14:29:13Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>You can quickly create a user selectable list of objects using CSS and a couple of quick dojo functions. First create a series of elements that you want the user to be able to select, and assign them all the same CSS class to describe their appearance. For example we'll create three &lt;xp:div&gt;'s.</p>
<blockquote>
<p>&lt;xp:div styleClass="userSelectable" id="div1"&gt;Example One&lt;/xp:div&gt;<br />&lt;xp:div styleClass="userSelectable" id="div2"&gt;Example Two&lt;/xp:div&gt;<br />&lt;xp:div styleClass="userSelectable" id="div3"&gt;Example Three&lt;/xp:div&gt;</p>
</blockquote>
<p>Now, lets define the userSelectable CSS class</p>
<blockquote>
<p>.userSelectable {<br />&nbsp;&nbsp; &nbsp;margin:4px;<br />&nbsp;&nbsp; &nbsp;height:20px;<br />&nbsp;&nbsp; &nbsp;border:1px solid #DDD;<br />&nbsp;&nbsp; &nbsp;background-color:#F3F3F3;<br />&nbsp;&nbsp; &nbsp;width:auto;<br />&nbsp;&nbsp; &nbsp;padding-left:24px;<br />&nbsp;&nbsp; &nbsp;background-image:url(AppIcon_mini.gif);<br />&nbsp;&nbsp; &nbsp;background-position:2px 2px;<br />&nbsp;&nbsp; &nbsp;background-repeat:no-repeat;<br />&nbsp;&nbsp; &nbsp;line-height:20px;<br />&nbsp;&nbsp; &nbsp;cursor:pointer;<br />&nbsp;&nbsp; &nbsp;cursor:hand;<br />}</p>
</blockquote>
<p>That should create an list that looks like this:</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/uisel1.gif?__SQUARESPACE_CACHEVERSION=1267973601331" alt="" /></span></span></p>
<p>Now, let's add two more definitions to our CSS. the first adds the :hover psuedo class, describing how the blocks should appear when the mouse is hovering over each item. We'll just override the background and border colors:</p>
<blockquote>
<p>.userSelectable:hover {<br />&nbsp;&nbsp; &nbsp;background-color:#EFEFEF;<br />&nbsp;&nbsp; &nbsp;border-color:#CCC;<br />}</p>
</blockquote>
<p>The final CSS markup we'll add is to define an additional class called focused that should alter the display of the item when the user has selected the item. To do this, we are going to specify ".userSelectable.focused" as the CSS selector. The lack of white space between the two class names means that both classes must be applied to the element for this markup to be applied.</p>
<blockquote>
<p>.userSelectable.focused {<br />&nbsp;&nbsp; &nbsp;background-color:#CCE6EE;<br />&nbsp;&nbsp; &nbsp;border-color:#92CADA;<br />}</p>
</blockquote>
<p>Now let's add a bit of javascript in the mix. You can place this in a client-side javascript library and include it in your XPage.</p>
<blockquote>
<p>function focusObject(class,objId) {<br />&nbsp; dojo.query(class+'.focused').removeClass('focused');<br />&nbsp; dojo.addClass(dojo.byId(objId), 'focused');<br />}</p>
</blockquote>
<p>The first line of the function finds any currently focused object and removes the focus from it, and the second line applies the focus to the object with the ID passed in as objId.</p>
<p>Now, let's modify our divs from above to include a bit of code to handle the click. On each div, place the following event handler code:</p>
<blockquote>
<p>&lt;xp:eventHandler event="onclick" submit="false"&gt;<br />&nbsp; &lt;xp:this.script&gt;<br />&nbsp;&nbsp;&nbsp; &lt;![CDATA[<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; focusObject('.userSelectable', '#{id:REPLACEWITHOBJECTID}');<br />&nbsp;&nbsp;&nbsp; ]]&gt;<br />&nbsp; &lt;/xp:this.script&gt;<br />&lt;/xp:eventHandler&gt;</p>
</blockquote>
<p>Make sure to replace the "REPLACEWITHOBJECTID" in the code above with the server side ID of the object. In our case, it would be div1, div2, or div3</p>
<p>Now, you have a user selectable list of elements. To retreive which element is selected at anytime, you can use</p>
<blockquote>
<p>dojo.query('.userSelectable.focused')[0]</p>
</blockquote>
<p>to get the node.</p>
<p>Here is what the code produces, the first div is in its normal state, the second is currently being hovered over (very subtle effect), and the third has been selected.</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/uisel2.gif?__SQUARESPACE_CACHEVERSION=1267973863538" alt="" /></span></span></p>]]></content></entry><entry><title>SSJS @Adjust on Javascript Dates - Be Backwarned!</title><category term="Date"/><category term="Tips and Tricks"/><category term="ssjs"/><id>http://xpagesblog.com/xpages-blog/2010/3/5/ssjs-adjust-on-javascript-dates-be-backwarned.html</id><link rel="alternate" type="text/html" href="http://xpagesblog.com/xpages-blog/2010/3/5/ssjs-adjust-on-javascript-dates-be-backwarned.html"/><author><name>Jeremy Hodge</name></author><published>2010-03-05T21:46:08Z</published><updated>2010-03-05T21:46:08Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>The following code will generate results that you may not expect:</p>
<blockquote>
<p>var myDate = new Date(2010,2,15);&nbsp; //this is MARCH 15th, months for JSDate is zero based<br />myDate = @Adjust(myDate,0,-1,0,0,0,0);</p>
</blockquote>
<p>You might expect myDate to now be 2/15/2010 ... its what the classic @Adjust @Formula would output.&nbsp; But there is a little more than meets the eye going on here.</p>
<p>new Date(2010,2,15) creates a new Date in the local time zone... In SSJS @Adjust() by default treats the date as a UTC timezone, so the results you will actually get is:<br /><br />2/14/2010<br /><br />Why you ask? Because we didnt specify a time in the date object, it's set to 12 Midnight, and going from March back to February crosses the line for Daylight savings, and the adjusted time changes from 12:00:00 midnight to 11:00:00 PM the previous day as you cross back.</p>
<p>The key is to specify the "[InLocalTime]" keyword to the @Adjust function, so the correct call would be:</p>
<blockquote>
<p>@Adjust(myDate,0,-1,0,0,0,0,"[InLocalTime]")</p>
</blockquote>
<p>Thanks to Dave Connelly and the IBM Team for chasing this one down!</p>
<p>&nbsp;</p>]]></content></entry><entry><title>Embedding Contextual Data for Client-Side Logic in XPages</title><id>http://xpagesblog.com/xpages-blog/2010/2/21/embedding-contextual-data-for-client-side-logic-in-xpages.html</id><link rel="alternate" type="text/html" href="http://xpagesblog.com/xpages-blog/2010/2/21/embedding-contextual-data-for-client-side-logic-in-xpages.html"/><author><name>Jeremy Hodge</name></author><published>2010-02-21T22:07:11Z</published><updated>2010-02-21T22:07:11Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>One of the difficulties I have faced when writing user-friendly UI's using XPages is the limited amount of "data" I can embed in a generated XPage for consumption by client side scripts.  Quite often I find myself wanting to do an dojo.xhrPost() to a domino agent to update the state of a document in the background, or programmatically post a partial refresh back to the server with programmatically contrived data, based on the user's actions, or the state of a dataset client-side. Quite often that action, or the target of that action is dependant upon one or more pieces of data that is not normally located in the DOM.</p>
<p>The typical way to embed this data in the document is through the use of the hidden input (&lt;xp:inputHidden /&gt; in XPages terms.)  When dealing with small amounts of data, this is fine, but what about more complex data sets, or large data sets. For example a list generated by an repeat control (&lt;xp:repeat /&gt;) can generate a large amount of hidden inputs, and you are still faced with the dilemma of how to programmatically determine which hidden input belongs to which UI element.</p>
<p>The solution is rather simple. We can embed our own contextual data tags directly into the HTML! Since browsers grew up and lived through the browser wars, when standards were something to be scoffed at, and the way to win user base was to have more cool tags than your competitor (&lt;blink&gt; anyone??) browsers have been taught to IGNORE tags they don't understand. We can use this to our advantage to embded data contextually within our HTML, then programmatically retrieve it.</p>
<p>To do this, you go to the code of your XPage, and just type in the new contextual data tag. For example, lets say we are dealing with a repeat control, and we want to get the UNID of each document that is rendered by the repeat. To do this we can code the following:</p>
<blockquote>
<p>&lt;xp:repeat var="listData" ...&gt;<br />   &lt;xp:panel id="myPanel"&gt;<br />     &lt;UNID value="#{javascript:listData.getUniversalID()}"&gt;</p>
<p>      [ ... other Xpages controls go here ... ]<br />   &lt;/xp:panel&gt;<br />&lt;/xp:repeat&gt;</p>
</blockquote>
<p>Now, when a user interacts with your "myPanel" for example, in a client-side onClick() event, you can easily retrieve the UNID for this document with the following code:</p>
<blockquote>
<p>var unid = dojo.attr(dojo.query('UNID', this.node)[0], 'value');</p>
</blockquote>
<p>This code has two important dojo functions. First the <a href="http://docs.dojocampus.org/dojo/query">query</a> function, which allows you to use almost all <a href="http://www.w3.org/TR/css3-selectors/#selectors">CSS3 selectors</a> to return a nodelist (an array of HTML nodes). The first argument to this function is the CSS selector used to located your nodes. In this case, we are asking for all UNID tags. This is a VERY powerful function. I would recommend that you study and learn its power. The second argument is the "root node" at which you want to start your search. If you omit this argument, the entire DOM is searched. If you include a Node, only descendant nodes of that Node will be searched. (Again this is very powerful. For example, XPages developers can use this to locate nodes based on the element's programmed ID, instead of the full client side-id by using the CSS3 selector [id$="myPanel"])</p>
<p>The second function is <a href="http://docs.dojocampus.org/dojo/attr">dojo.attr</a> which returns the value of the attribute specified in argument 2, from the node specified in argument 1.</p>
<p>While this example is over-simplified, you can imagine the powerful things you could put this to use in. For example, off the top of my head, i can think of using contextual data tags to:</p>
<ul>
<li>pass information that may be required for display in tooltips, popups, or other display-only interfaces, without having to pass all the markup associated with it (especially when it can be generated client-side, then discarded</li>
<li>passing identifying data, such as UNIDs, to use in ajax calls back to the server to simulate <a href="http://en.wikipedia.org/wiki/Representational_State_Transfer">RESTful</a> API/<a href="http://en.wikipedia.org/wiki/Create,_read,_update_and_delete">CRUD</a> calls.</li>
<li>And, since you can nest the tags, you can give the data relational meaning (think embedded XML)</li>
</ul>
<p>Happy Coding!</p>
<p> </p>]]></content></entry><entry><title>XPages101 Online offers affordable XPages training</title><category term="Resources"/><category term="Training"/><category term="xpages101"/><id>http://xpagesblog.com/xpages-blog/2010/2/15/xpages101-online-offers-affordable-xpages-training.html</id><link rel="alternate" type="text/html" href="http://xpagesblog.com/xpages-blog/2010/2/15/xpages101-online-offers-affordable-xpages-training.html"/><author><name>Matt White</name></author><published>2010-02-15T08:12:06Z</published><updated>2010-02-15T08:12:06Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>On Friday I announced over on <a href="http://mattwhite.me/blog/2010/2/12/xpages101-online-is-here.html">my blog</a> about <a href="http://xpages101.net">XPages101 Online</a>. It's an online version of my one day introduction to XPages course with full videos and supporting content to guide you through building an XPages application from start to finish.</p>
<p>But to add extra value, and help you as you progress in your XPages development, I'll be uploading a new video based lesson every week which will walk you through some aspect of XPages development, whether it be using Java classes in your Server Side Javascript, making the most of the Dojo framework which ships with Domino or extending the standard controls which you can use in your XPages and Custom Controls.</p>
<p>Until 26th February, there is a special offer running which offers a 33% discount on the subscription fee if you enter the coupon code "earlybird" at checkout.</p>]]></content></entry><entry><title>Complete Turnkey NSF to Transform DXL into XPage Syntax</title><category term="DXL"/><category term="Development"/><category term="Resources"/><category term="SNTT"/><category term="Tips and Tricks"/><category term="XML"/><category term="XPages"/><category term="XSLT"/><id>http://xpagesblog.com/xpages-blog/2010/2/11/complete-turnkey-nsf-to-transform-dxl-into-xpage-syntax.html</id><link rel="alternate" type="text/html" href="http://xpagesblog.com/xpages-blog/2010/2/11/complete-turnkey-nsf-to-transform-dxl-into-xpage-syntax.html"/><author><name>Paul Calhoun</name></author><published>2010-02-11T14:33:14Z</published><updated>2010-02-11T14:33:14Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>I posted an <a href="http://xpagesblog.com/xpages-blog/2010/2/7/updated-transforming-domino-forms-into-xpages-via-xslt.html">entry</a>&nbsp;earlier this week on an update to the stylesheet I created and demonstrated at Lotusphere on how to transform Domino Form, Sub-Form and Shared Fields DXL into XPage syntax that could be copied and pasted directly into the XPages source tab in the Domino Designer client.</p>
<p>I had updated it to include the processing of Sub-Forms and Shared Fields.&nbsp; The problem was that it placed the fields from the sub-forms and shared fields at the bottom of the XPage instead of in-line where the sub-forms and shared fields appeared in the original Domino Form design.&nbsp; Well I'm happy to announce two things.</p>
<ol>
<li>I have updated the Stylesheet so that it processes Sub-Forms and Shared Fields In-Line.</li>
<li>I created a compete turnkey Notes based application that allows developers to complete the transformations and save the results.</li>
</ol>
<p>In updating the style sheet I was not pleased with the procedure for having to select the design elements from the dialog box in the designer client.&nbsp; You couldn't tell from one selection to the next what you had selected and the results were not saved, but displayed in the browser.</p>
<p>In the turnkey Notes application I have made available on my <a href="http://www.nnsu.com">download site</a>&nbsp;today I have created a Form that allows developers to choose an application from their local system or a server, select the Forms, Sub-Forms and Shared Fields to be transformed and simply click an action in the action bar to perform the transformation and save the results in a document in the application.</p>
<p>Everything is included in the application.&nbsp; Nothing else needs to be downloaded.</p>
<p>The individual stylesheet is available for download as well if you don't want to download the complete application.</p>
<p>Here is a summary of the new steps.</p>
<p>You will need an 8.5 or 8.5.1 system.</p>
<p>Download the application from my website to your local data directory and sign it with your ID</p>
<p>Open the application and click on the "Create New Exporter"&nbsp;action in the action bar.</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/NewTransimg1.png?__SQUARESPACE_CACHEVERSION=1265899985105" alt="" /></span></span></p>
<p>&nbsp;</p>
<p>This will load the following form where you can select the design elements to be included in the transformation.&nbsp; The&nbsp;ConvertForm stylesheet is currently the only one included but this design allows for any number of stylesheets to be added and used.&nbsp; Once all the elements are selected click on the "Run DXL Transformation" action in the action bar.</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/NewTransimg2.png?__SQUARESPACE_CACHEVERSION=1265900258407" alt="" /></span></span></p>
<p>&nbsp;</p>
<p>This will transfrom the selected elements and save them in a docment in the "Transformed XPage Results View"</p>
<p>This document can be opened and the XPage syntax copied to the clipboard using the button in the form.</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/NewTransimg3.png?__SQUARESPACE_CACHEVERSION=1265900862309" alt="" /></span></span></p>
<p>&nbsp;</p>
<p>Then open an XPage in the Designer client and replace the existing XPage code on the source tab with the code from the clipboard.</p>
<p>And thats it !!</p>
<p>I have implemented this solution so if there are additional stylesheets I (or you)&nbsp;create in the future they can simply be added as an additional stylesheet to choose from in the stylesheets view.</p>
<p>As always I appreciate any feedback ya'll might have on additions and improvements.</p>
<p>Again the complete turnkey application can be downloaded from <a href="http://www.nnsu.com">here</a>.</p>
<p>Thanks !!!</p>]]></content></entry><entry><title>UPDATED: Transforming Domino Forms into XPages via XSLT</title><category term="Development"/><category term="Tips and Tricks"/><category term="Tutorial"/><category term="XML"/><category term="XPages"/><category term="XSLT"/><id>http://xpagesblog.com/xpages-blog/2010/2/7/updated-transforming-domino-forms-into-xpages-via-xslt.html</id><link rel="alternate" type="text/html" href="http://xpagesblog.com/xpages-blog/2010/2/7/updated-transforming-domino-forms-into-xpages-via-xslt.html"/><author><name>Paul Calhoun</name></author><published>2010-02-08T05:02:51Z</published><updated>2010-02-08T05:02:51Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>First I want to thank everyone who came to the XML and Web Services Jumpstart as well as the speedgeeking at Lotusphere 10.&nbsp; I got a lot of great feedback.&nbsp; Thanks !!!</p>
<p>One such feedback was about my process of transforming Domino Form Designs into XPages via XSLT.&nbsp; When I developed the tool I took what I believed to be a logical approach and added all of the different field types to a Domino Form Design and then processed it with the XSLT stylesheet I created.</p>
<p>Everything came across, all of the fields were processed I was very proud.&nbsp; Then someone at lotusphere asked me "Paul this process works great when the fields are defined on the form itself, but most of my forms have sub-forms and shared fields that don't seem to be transformed via your process.&nbsp; How come?"</p>
<p>Then I had a real "well duh !!!" moment.&nbsp; A Domino form that contains a sub-form or shared field does not include the field definitions for those elements, simply a reference to the sub-form or shared field.</p>
<p>Suddenly I was not so proud as I don't think I have ever developed a Domino form that did not contain a sub-form or shared field.&nbsp;</p>
<p>So I have set out rectify this issue by adding the processing of sub-forms and shared fields to the transformation process.</p>
<p>If you are not familiar with the process see <a href="http://xpagesblog.com/xpages-blog/2009/7/23/transforming-domino-forms-into-xpages-via-xslt.html">this article</a> for detailed instructions.</p>
<p>So what is different about the new process is that when selecting design elements to be transformed, you can choose multiple elements.&nbsp; Whatever you select will be included in the DXL to be transformed.</p>
<p>In the Domino Designer client open the application that contains the elements to be transformed.</p>
<p>Choose Tools | DXL Utilities | Transformer...</p>
<p>&nbsp;<span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/transimg1.png?__SQUARESPACE_CACHEVERSION=1265606421835" alt="" /></span></span></p>
<p>&nbsp;</p>
<p>In the dialog box that opens select the primary form to be transformed</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/transimg2.png?__SQUARESPACE_CACHEVERSION=1265606793513" alt="" /></span></span></p>
<p>Next select any sub-forms to be included in the transformation</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/transimg3.png?__SQUARESPACE_CACHEVERSION=1265606829608" alt="" /></span></span></p>
<p>Last select any shared fields to be included in the transformation.&nbsp;&nbsp;</p>
<p>Lastly choose the stylesheet from the list of available stylesheets to perform the transformation and click the OK button.</p>
<p>&nbsp;<span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/transimg4.png?__SQUARESPACE_CACHEVERSION=1265606858936" alt="" /></span></span></p>
<p>&nbsp;</p>
<p>The fields from the selected sub-forms and selected shared fields will be at the bottom of the transformed XPage.&nbsp;</p>
<p><span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/transimg5.png?__SQUARESPACE_CACHEVERSION=1265607109331" alt="" /></span></span></p>
<p>I'm working on a way to get them "in-line" but wanted to get this solution out there as soon as possible.</p>
<p>The new XSLT stylesheet is called "DominoDBDXLToXPageWithSubForm.xsl" and is available from my <a href="http://www.nnsu.com">web site</a>in the downloads link.</p>
<p>Once again thanks for all of the feedback and I will continue to try and improve this process.</p>
<p>&nbsp;</p>]]></content></entry><entry><title>UPDATE: Self Awareness of Custom Controls in XPages: "Am I alone out there"</title><category term="XPages"/><category term="custom controls"/><category term="instance"/><id>http://xpagesblog.com/xpages-blog/2010/2/4/update-self-awareness-of-custom-controls-in-xpages-am-i-alon.html</id><link rel="alternate" type="text/html" href="http://xpagesblog.com/xpages-blog/2010/2/4/update-self-awareness-of-custom-controls-in-xpages-am-i-alon.html"/><author><name>Lance Spellman</name></author><published>2010-02-04T22:56:44Z</published><updated>2010-02-04T22:56:44Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>UPDATE:&nbsp; Jeremy Hodge points out the built-in method XPages has for allowing you to do this in the comment below.&nbsp; Based on that, I've updated the demo and re-recorded it.&nbsp; So, if you've watched the first one, watch the new one.&nbsp; The premise, or needs, are the same as what's described below.&nbsp; The solution is better.</p>
<p>The better approach:</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/6e-TC-iWY1E&hl=en_US&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/6e-TC-iWY1E&hl=en_US&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>---</p>
<p>&nbsp;</p>
<p>What the heck does that mean???&nbsp; Well, here's a scenario. I've taken the time to build a PieChart custom control.&nbsp; I'd like to be able to drop that PieChart on an XPage multiple times for multiple different charts.&nbsp; But how can I make that happen without hard-coding the configuration into the control itself?&nbsp; I would need to be able to PASS that data into the PieChart control from the containing page.&nbsp;</p>
<p>So if I use something like viewScope.put('PieChartConfig', config) into the XPage, that solves getting data TO the control, but only for 1 instance of the control.&nbsp; For example, the control would receive that data with viewScope.get('PieChartConfig', config).&nbsp; But now I can only have 1 control on the page because each instance of the control would be getting the same config.</p>
<p>Somehow each INSTANCE of the control has to be able to get its own data configuration.&nbsp; Here's how.</p>
<p>When we put each instance of the PieChart custom control on the XPage, we're allowed to name that instance, just like we name any other control.&nbsp; So, PieChart1, PieChart2, etc...</p>
<p>Now from the XPage, we can modify our earlier code and do something like this:</p>
<p>viewScope.put('PieChartConfig', {'PieChart1':config1, 'PieChart2':config2});</p>
<p>Inside the PieChart control, we can get the config that's intended for that instance by having a control on the page like a computed field with the name of 'sId' which has the value of:</p>
<p>var idArray = getClientId('sId').split(':');<br />idArray[idArray.length-2]</p>
<p>This will be the name assigned to the custom control instance inside the containing XPage.</p>
<p>To get the config that's specific to this instance of the control, we'd use:</p>
<p>var ConfigAll = viewScope.get('PieChartConfig');<br />var ConfigMe = d[getComponent('sId').value]</p>
<p>I've recorded a quick (2 min) video example of this, and <a href="http://xpagesblog.com/storage/selfaware.nsf">an .nsf</a><a href="http://xpagesblog.com/storage/selfaware.nsf"></a> with that code.&nbsp; Hope this helps.</p>
<p><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/DNdHq-_95nk&hl=en_US&fs=1&"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/DNdHq-_95nk&hl=en_US&fs=1&" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object></p>
<p>&nbsp;</p>
<p>&nbsp;</p>]]></content></entry><entry><title>XPiNC Hello World - XPages in the Sidebar on a Composite App.</title><category term="Sidebar"/><category term="Tutorial"/><category term="XPiNC"/><id>http://xpagesblog.com/xpages-blog/2010/2/3/xpinc-hello-world-xpages-in-the-sidebar-on-a-composite-app.html</id><link rel="alternate" type="text/html" href="http://xpagesblog.com/xpages-blog/2010/2/3/xpinc-hello-world-xpages-in-the-sidebar-on-a-composite-app.html"/><author><name>Paul Hannan</name></author><published>2010-02-03T21:07:19Z</published><updated>2010-02-03T21:07:19Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Here is a quick post on how you can add a XPage to the Sidebar in the Notes Client. Currently this is the only way you can put a XPage in the Sidebar, the other way may be in the future.</p>
<p>So lets start. Take any Composite Application and from the main menu select <strong>Actions</strong> - <strong>Edit Application</strong>.<img src="http://xpagesblog.com/storage/x01EditCA.jpg?__SQUARESPACE_CACHEVERSION=1265232045133" alt="" /></p>
<p>This will open the application in the Composite App Editor. And here we're going to add a XPage Component that has been configured for wiring events (for more on this try this Wiki <a href="http://www-10.lotus.com/ldd/ddwiki.nsf/dx/XPage_Components_in_Notes_851_Videos.htm">post</a>). On the Component Palette select to add a new NSF Component.<span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/x02AddNSFComponent.jpg?__SQUARESPACE_CACHEVERSION=1265232247092" alt="" /></span></span></p>
<p>Name and select the XPage Component from any application, and select OK.<br /><span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/x03NewNSFComponent.jpg?__SQUARESPACE_CACHEVERSION=1265232732279" alt="" /></span></span></p>
<p>&nbsp;With the component now created, drag and drop this component from the Palette to the Sidebar.<span class="full-image-block ssNonEditable"><span><img style="width: 600px;" src="http://xpagesblog.com/storage/x04DnDCompSidebar.jpg?__SQUARESPACE_CACHEVERSION=1265234698163" alt="" /></span></span></p>
<p>You can save your changes as they are and your XPage will now appear in the Sidebar, but we're going a step further and wire up the publish and receive events.</p>
<p>With the desired page of the Composite App open, right mouse click on the XPage component in the Sidebar and choose the option <strong>Edit Wiring</strong>.<span class="full-image-block ssNonEditable"><span><img src="http://xpagesblog.com/storage/x05WireSideBar.jpg?__SQUARESPACE_CACHEVERSION=1265233509643" alt="" /></span></span></p>
<p>&nbsp;Using the wiring page...&nbsp;</p>
<p><span class="full-image-block ssNonEditable"><span><img style="width: 600px;" src="http://xpagesblog.com/storage/x06WiringComponents.jpg?__SQUARESPACE_CACHEVERSION=1265234782059" alt="" /></span></span></p>
<p>...wire up the publish and receive events.</p>
<p><span class="full-image-block ssNonEditable"><span><img style="width: 600px;" src="http://xpagesblog.com/storage/x07WiredComponents.jpg?__SQUARESPACE_CACHEVERSION=1265234825845" alt="" /></span></span></p>
<p>Save and close the application in the Composite App Editor.&nbsp;</p>
<p>Launching the Composite App the XPage component will now display in the side bar.</p>
<p><span class="full-image-block ssNonEditable"><span><img style="width: 600px;" src="http://xpagesblog.com/storage/x08XPagesSidebar.jpg?__SQUARESPACE_CACHEVERSION=1265234843662" alt="" /></span></span></p>
<p>&nbsp;And the wiring will work from here too.</p>
<p><span class="full-image-block ssNonEditable"><span><img style="width: 600px;" src="http://xpagesblog.com/storage/x09XPagesSidebarWiring.jpg?__SQUARESPACE_CACHEVERSION=1265234875669" alt="" /></span></span></p>]]></content></entry></feed>