<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.11.81 (http://www.squarespace.com/) on Sun, 12 Feb 2012 04:43:06 GMT--><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>John Liu .NET: Time for Fun in SharePoint</title><link>http://johnliu.net/blog/</link><description></description><lastBuildDate>Sun, 05 Feb 2012 04:56:17 +0000</lastBuildDate><copyright>(c) John Liu</copyright><language>en-US</language><generator>Squarespace Site Server v5.11.81 (http://www.squarespace.com/)</generator><item><title>InfoPath how to copy a repeating section using rules</title><category>InfoPath</category><category>SharePoint</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Sun, 05 Feb 2012 04:56:17 +0000</pubDate><link>http://johnliu.net/blog/2012/2/5/infopath-how-to-copy-a-repeating-section-using-rules.html</link><guid isPermaLink="false">358543:3878987:14878937</guid><description><![CDATA[<p>For years, we all thought this was impossible.&#160; You had to use code.&#160; I somehow woke up with an idea on how to do this, and set about testing and to my surprise, found a solution.&#160; Here it is!</p>  <p>&#160;</p>  <h3>The form set up</h3>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418952" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418953" width="182" height="267" /></a></p>  <ul>   <li>Two repeating sections, Foo's and Bar's</li>    <li>One additional integer field i to control which row to copy</li> </ul>  <p>Put the elements on the form:</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418954" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418955" width="653" height="369" /></a></p>  <p>&#160;</p>  <p>&#160;</p>  <h3>The copy rule</h3>  <p>Create a rule on the integer field i</p>  <ol>   <li>We will use the normal action, then tweak it.&#160; <br />Give this rule the name <strong>&quot;Copy&quot;</strong>      <br />Start by defining a set field value rule.      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418956" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418957" width="235" height="511" /></a>      <br /></li>    <li>Set /my:myFields/my:Foos/my:Foo/my:F1 to /my:myFields/my:Bars/my:Bar/my:B1     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418968" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418970" width="494" height="305" /></a>      <br />      <br />There are a few issues so far with the default Set Field Value action related to a repeating section.</li>    <ul>     <li>For the Field (target), it will set ALL the matching nodes.</li>      <li>For the Value, it will get the First matching node.       <br /></li>   </ul>    <li>Let's fix the second value - we can do this in InfoPath designer.     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418971" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418972" width="603" height="268" /></a>      <br />      <br />The expression is:      <br />../my:Bars/my:Bar[number(../../my:i)]/my:B1      <br />      <br />This expression lets us copy a different row.      <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418973" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418974" width="494" height="305" /></a>      <br />      <br />So we can now copy value from any row - depending on what the number i is.      <br /></li>    <li>To fix the Field Target is a bit more difficult.&#160; InfoPath designer doesn't give us a way to modify the XPath of the field.     <br />      <br /></li>    <li>Save the form.&#160; We're about to do <em>unsupported </em>stuff.&#160; </li>    <li>Publish the form to Source Files.&#160; <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418976" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418977" width="496" height="143" /></a>      <br />      <br />I publish to C:\Temp\CopyForm\      <br /></li>    <li>Close InfoPath designer.&#160; Open the file C:\Temp\CopyForm\manifest.xsf file using NotePad or your favourite XML editor.     <br /></li>    <li>The &quot;Copy&quot; rule is hiding in this XML file, it looks like this:     <br /></li>    <p>&lt;xsf:rule caption=&quot;Copy&quot;&gt;     <br />&#160;&#160;&#160; &lt;xsf:assignmentAction targetField=&quot;../my:Foos/my:Foo/my:F1&quot; expression=&quot;../my:Bars/my:Bar[number(../../my:i)]/my:B1&quot;&gt;&lt;/xsf:assignmentAction&gt;      <br />&lt;/xsf:rule&gt;</p>    <li>Change it to:     <br /></li> &lt;xsf:rule caption=&quot;Copy&quot;&gt;    <br />&lt;xsf:assignmentAction targetField=&quot;../my:Foos/my:Foo<strong><u><font style="background-color: #ffff00">[number(../../my:i)]</font></u></strong>/my:F1&quot; expression=&quot;../my:Bars/my:Bar[number(../../my:i)]/my:B1&quot;&gt;&lt;/xsf:assignmentAction&gt;    <br />&lt;/xsf:rule&gt;    <li>Save, and close Notepad.&#160; Re-open manifest.xsf file using InfoPath Designer     <br /></li>    <li>Let's check our rule.     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418979" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418980" width="494" height="305" /></a>      <br /></li>    <li>Are you thinking what I'm thinking?&#160; We're nearly there.</li> </ol>    <h3>The loop</h3>  <ol>   <li>This rule is set on the number <em>i</em>, and runs once whenever the number <em>i</em> changes.      <br /></li>    <li>Lets set it up to increment.     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418981" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418982" width="235" height="495" /></a>      <br /></li>    <li>Add a condition to stop incrementing when we've run out of rows     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418983" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418984" width="623" height="131" /></a>      <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418985" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418986" width="234" height="458" /></a>      <br /></li>    <li>And to start the whole thing, remember we have a button.     <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418987" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418988" width="234" height="459" /></a>      <br />      <br />To start the process, set i to 1.&#160; XML index starts from 1 to n.&#160; Does not start at 0.      <br /></li> </ol>  <p>&#160;</p>  <h3>Result - InfoPath Filler</h3>  <p>   <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418989" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418990" width="384" height="389" /></a>    <br />Starting...    <br />    <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418992" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418993" width="388" height="386" /></a></p>  <p>Press &quot;Copy&quot;   <br />    <br /></p>  <h3>Result - Form Server:</h3>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418994" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418995" width="288" height="412" /></a></p>  <p>Starting Browser Form   <br /></p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418996" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418997" width="306" height="405" /></a></p>  <p>Copy.</p>  <p>&#160;</p>  <h3>Note - InfoPath &quot;Infinite Loop&quot; limitation:</h3>  <p>InfoPath is hard coded to only execute 16 rules before throwing the &quot;Infinite Loop&quot; error.   <br />    <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418998" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-to-copy-a-repeating-section-usi_D354-?fileId=16418999" width="669" height="262" /></a>    <br />    <br />An error occurred in the form's rules or code. The number of rule actions or the number of calls to the OnAfterChange event for a single update in the data exceeded the maximum limit.</p>  <p>The rules or code may be causing an infinite loop. To prevent this, ensure that the rule action or event handler does not update the data which causes the same rule action or event handler to execute.   <br /></p>  <p>&#160;</p>  <p>There is no solution for hard coded 16 rules.&#160; So your <em>i</em> can not go over 16.    <br /></p>  <h3>Download</h3>  <ul>   <li><a title="http://johnliu.net/storage/CopyForm.xsn" href="http://johnliu.net/storage/CopyForm.xsn">http://johnliu.net/storage/CopyForm.xsn</a></li> </ul>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-14878937.xml</wfw:commentRss></item><item><title>Pretty up SharePoint 2010 mysite with showModalDialog (updated)</title><category>SharePoint</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Sun, 05 Feb 2012 02:39:01 +0000</pubDate><link>http://johnliu.net/blog/2012/2/5/pretty-up-sharepoint-2010-mysite-with-showmodaldialog-update.html</link><guid isPermaLink="false">358543:3878987:14877005</guid><description><![CDATA[<p>[This is an updated article from <a href="http://johnliu.net/blog/2011/8/3/sp2010-pretty-up-mysite-with-showmodaldialog.html">http://johnliu.net/blog/2011/8/3/sp2010-pretty-up-mysite-with-showmodaldialog.html</a>.]</p>  <p>&#160;</p>  <h3>SharePoint 2010 My Site</h3>  <p>SharePoint 2010 ships with this pretty mysite.&#160; Packed with numerous features.</p>  <p><img alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SP2010---keep-your-un-themed-mysite_112B1-?fileId=13500297" /></p>  <p>&#160;</p>  <p>The problem with My Site, even back in the days of SharePoint 2007, is that your users get lost.&#160; It doesn’t look anything like your nice branded site.&#160; It doesn’t share the same global navigation.&#160; In fact, users are so lost that they think they are in a place that they shouldn’t be in. </p>  <p>Result?&#160; They close the browser.&#160; Sometimes, if they are nasty, they tell their colleagues that the Intranet sucks - they can never find anything.&#160; </p>    <p>&#160;</p>  <p>If only we can render our mysite in a SharePoint 2010 showModalDialog, then it would look like this:</p>  <h3>My Site in a modal dialog</h3>  <p><img alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SP2010---keep-your-un-themed-mysite_112B1-?fileId=13500300" /></p>  <p>&#160;</p>  <p>Some of the immediate benefits:</p>  <ul>   <li>My Site remains totally un-branded, but now it is just demoted to an utility page.&#160; That is, you keep the functionality without having to invest in how to make My Site look nice.</li>    <li>Users are familiar with the SharePoint modal dialog, and can easily close My Site via the top right close buttons. </li>    <li>Users don’t feel like they’ve left the site, because they can clearly see the previous page right beneath them.</li> </ul>  <p>&#160;</p>  <h3>Using modal dialog for user information</h3>  <p>Even if you aren't using My Site, you can still use this for links on the page that would lead you to a user's information page.&#160; Here's an example:</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-Pretty-up-SharePoint-2010-mysite-with-sh_B37A-?fileId=16417976" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-Pretty-up-SharePoint-2010-mysite-with-sh_B37A-?fileId=16417977" width="403" height="151" /></a></p>  <p>&#160;</p>  <p>You click the user name, you are sent to the User Information page - completely losing your previous page.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-Pretty-up-SharePoint-2010-mysite-with-sh_B37A-?fileId=16417978" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-Pretty-up-SharePoint-2010-mysite-with-sh_B37A-?fileId=16417980" width="806" height="533" /></a></p>  <p><strong>Figure: EEk!&#160; Where the heck am I?</strong></p>  <p>We add this bit of jQuery</p>  <p>$(function(){   <br />&#160;&#160;&#160; $(&quot;a[href*='userdisp']&quot;).click(function(e){    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; SP.UI.ModalDialog.showModalDialog({     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; url: $(this).attr(&quot;href&quot;),     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; autoSize: true     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; });&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; e.preventDefault();    <br />&#160;&#160;&#160; }).attr(&quot;onclick&quot;,&quot;&quot;);    <br />});    <br /></p>  <p>This hooks into any &lt;a&gt; anchors on the page, whose href contains the word &quot;userdisp&quot;.&#160; And then override the onclick attribute to empty.&#160; It also attaches a new click event handler, sending the click to a show modal dialog.&#160; Lastly, it prevents default - so the default action from the click is swallowed.</p>  <h3>Result - User Information in a pop up:</h3>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-Pretty-up-SharePoint-2010-mysite-with-sh_B37A-?fileId=16417981" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-Pretty-up-SharePoint-2010-mysite-with-sh_B37A-?fileId=16417982" width="751" height="460" /></a></p>  <p><strong>Figure: Now isn't this far more useful?!</strong></p>  <p>&#160;</p>  <h3>Changing My Site</h3>  <p>We have these two links that sends our users into Alice's Wonderland.</p>  <p><img alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SP2010---keep-your-un-themed-mysite_112B1-?fileId=13500302" /></p>  <p>&#160;</p>  <p>They both use a SharePoint JavaScript function STSNavigate2</p>  <p>We can override the JavaScript this way:</p>  <p>I did a simple prototype by overriding a SharePoint javascript function:</p>  <p>&#160;</p>  <p>$(function(){   <br />&#160;&#160;&#160; // store a reference to the STSNavigate2 function    <br />&#160;&#160;&#160; window.oldSTSNavigate2 = window.STSNavigate2;    <br />&#160;&#160;&#160; window.STSNavigate2 = function (evt, Url){    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (Url.indexOf(&quot;mysite&quot;) != -1) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // if the url contains mysite - open it in showModalDialog    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SP.UI.ModalDialog.showModalDialog({    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; url: Url,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; title: &quot;My Site&quot;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; autoSize: true    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; // otherwise call the old version of STSNavigate2    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; window.oldSTSNavigate2(evt, Url);    <br />&#160;&#160;&#160; };    <br />});</p>  <p>&#160;</p>  <h3>Result - My Site in a pop up:</h3>  <p><img alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SP2010---keep-your-un-themed-mysite_112B1-?fileId=13500300" /></p>  <p>&#160;</p>  <h3>Notes - some odd CSS issues:</h3>  <p>When a page is rendered in the modal dialog, SharePoint will automatically insert &amp;IsDlg=1 to the argument.</p>  <p>My Site doesn't appear to have been <em>exhaustively</em> tested with IsDlg - and there are odd CSS issues that does appear.&#160; Depending on the features that you plan to activate on your My Site, you may still need to invest in a small bit of CSS work to make sure nothing strange appears when My Site is shown in a Pop Up.</p>  <p>Still, I argue that the small CSS fixes are a lot less work than completely rebranding your My Site.</p>  <p>In general though, majority of the functionality are available without further modification and this is a good way to quickly test if this could work for you and your organisation.&#160; Do let me know how this works for you!</p>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-14877005.xml</wfw:commentRss></item><item><title>SharePoint - JavaScript current page context info</title><category>SharePoint</category><category>code</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Fri, 03 Feb 2012 06:38:20 +0000</pubDate><link>http://johnliu.net/blog/2012/2/3/sharepoint-javascript-current-page-context-info.html</link><guid isPermaLink="false">358543:3878987:14853026</guid><description><![CDATA[  <p>Quick blog. On every SharePoint page there's a javascript context variable:</p>  <pre> _spPageContextInfo <br />{<br />    webServerRelativeUrl : &quot;/ProjectWeb&quot;,<br />    webLanguage : 1033,<br />    currentLanguage : 1033,<br />    webUIVersion : 4,<br />    pageListId : &quot;{c1d7b89f-f07b-4e2e-b89c-76c315831d59}&quot;,<br />    pageItemId : 5,<br />    userId : 68,<br />    alertsEnabled : true,<br />    siteServerRelativeUrl : &quot;/&quot;,<br />    allowSilverlightPrompt : &quot;True&quot;<br />} </pre>

<pre>So if you are on /ProjectWeb/Pages/default.aspx</pre>

<pre>_spPageContextInfo.pageListId;   // list guid for Pages<br />_spPageContextInfo.pageItemId;   // ID for listitem<br /></pre>

<p>&#160;</p>

<h3>Special Note</h3>

<p>siteServerRelativeUrl will tell you if your site collection is sitting at the root level, or mapped further down.&#160; Fairly useful information for all sorts of mischief.</p>

<p>No idea why alertsEnabled is a useful information.</p>

<p>&#160;</p>

<h3>An Example </h3>

<p>Say if you want to show the versions page:</p>

<pre>var options = {<br />    tite: &quot;Version History&quot;,<br />    url: _spPageContextInfo.webServerRelativeUrl + &quot;/_layouts/Versions.aspx?list=&quot;+ _spPageContextInfo.pageListId +&quot;&amp;ID=&quot;+ _spPageContextInfo.pageItemId,<br />    width: 800,<br />    height: 500,<br />};<br />SP.UI.ModalDialog.showModalDialog(options);</pre>

<p>&#160;</p>

<p>This will get you the Version History page in a modal popup, without running any additional client context async query.</p>

<p><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---current-page-context-in-Jav_F546-?fileId=16389688" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---current-page-context-in-Jav_F546-?fileId=16389689" width="475" height="211" /></a></p>

<p><strong>Figure: Version History showing in a modal popup.</strong></p>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-14853026.xml</wfw:commentRss></item><item><title>Australian SharePoint Conference 2012, March 20-21, Melbourne</title><category>Public Announcement</category><category>SharePoint</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Fri, 20 Jan 2012 16:11:36 +0000</pubDate><link>http://johnliu.net/blog/2012/1/20/australian-sharepoint-conference-2012-march-20-21-melbourne.html</link><guid isPermaLink="false">358543:3878987:14661860</guid><description><![CDATA[  <p><img style="margin: 0px 16px 0px 0px; display: inline; float: left" align="left" src="http://johnliu.net/storage/AUSSPCsquare.png" width="240" height="119" />2012 will be the third <a href="http://www.sharepointconference.com.au/">Australian SharePoint Conference</a> [<a href="http://www.sharepointconference.com.au/2012/SitePages/ConferenceAgenda.aspx">agenda</a>], and my third time speaking at this fantastic event. In my opinion, the AUSPC conference has some of the world's best speakers (and I gladly exclude myself from that list), exceeding even the Australian Tech-Ed event in terms of breadth and depths of SharePoint content. There are simply no other event this dedicated to SharePoint within Australia.</p>  <p>In the year 2011 we saw tremendous growth in SharePoint, and new techniques with jQuery becoming very popular. </p>  <p><a href="http://johnliu.net/sharepoint-and-silverlight/">Silverlight</a> is now moving towards a backseat, to my dismay - I argue that it remains a very useful arsenal in providing the <a href="http://johnliu.net/blog/2012/1/9/pasting-pictures-from-clipboard-to-sharepoint-in-browser-via.html">tools</a> to extend SharePoint's <a href="http://johnliu.net/blog/2010/7/16/sharepoint-2010-and-silverlight-40-webcam.html">capabilities</a>, but with the advances in HTML5 and the myriad of devices that our users are now plugging to SharePoint, a different future is fast approaching, and it doesn't look <em>that great </em>for Silverlight.</p>  <p>In the new year 2012, I think there will be stronger focus in using HTML5 and JavaScript going forward, with may be a good sprinkle of Metro, pending Windows 8's release. </p>    <p>I will be presenting an updated version of my talk &quot;Building your own Custom REST services and consuming them with jQuery AJAX&quot;. Time permitting, I want to add a tiny section on KnockoutJS. Aside from future SharePoint Saturday events, I'll be posting the entire REST services talk in a series of blog posts in the upcoming months.</p>  <p>Also, consider the sad cancellation of January's Sydney SharePoint User Group, I hope to be able to present a talk on KnockoutJS in a Developer session as early as February, fingers crossed. A previous version of my talk on <a href="http://johnliu.net/blog/2011/10/18/sspug-rest-service-and-jquery-ajax.html">REST services</a> is still here.</p>  <p>If you thought you've seen everything there is to know about SharePoint, hold on to your seatbelts, because you are about to be blown away! See you soon around Australia, our first stop, in the <a href="http://www.sharepointconference.com.au/">Australian SharePoint Conference</a>, March 20-21.</p>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-14661860.xml</wfw:commentRss></item><item><title>InfoPath - LoadDocumentAndPlayEventLog NullReferenceException</title><category>InfoPath</category><category>SharePoint</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Wed, 18 Jan 2012 02:37:59 +0000</pubDate><link>http://johnliu.net/blog/2012/1/18/infopath-loaddocumentandplayeventlog-nullreferenceexception.html</link><guid isPermaLink="false">358543:3878987:14628525</guid><description><![CDATA[<p>Error:</p>  <blockquote>   <p>LoadDocumentAndPlayEventLog failed with unhandled exception System.NullReferenceException: Object reference not set to an instance of an object.&#160;&#160;&#160;&#160; at Microsoft.Office.InfoPath.Server.Converter.DetectUnsupportedNamespaces.VerifyNamespace</p> </blockquote>  <p>This is a very <em>uncommon</em> bug.&#160; Essentially, you are using custom code in InfoPath, and you are using code that doesn't have a namespace.&#160; Say a helper function that you've included in your code.</p>  <p>When InfoPath Forms Services attempt to validate your form, it finds that your form template contains reference to code that doesn't have a namespace!</p>  <p>The fix is simple, create a namespace for the helper class, or move the helper class under the namespace of the form's namespace.</p>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-14628525.xml</wfw:commentRss></item><item><title>SharePoint - here is a REST service Project Item template</title><category>SharePoint</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Mon, 16 Jan 2012 14:08:44 +0000</pubDate><link>http://johnliu.net/blog/2012/1/16/sharepoint-here-is-a-rest-service-project-item-template.html</link><guid isPermaLink="false">358543:3878987:14600197</guid><description><![CDATA[<p>CKSDEV provides a wonderful WCF template.&#160; The main magic of this template is that it uses SharePoint 2010's MultipleBaseAddressBasicHttpBindingServiceHostFactory to create a service host and hook up all the configuration settings.&#160; This is done by the hardwork <a href="http://www.chaholl.com/">Charlie Holland</a> and described here <a href="http://www.chaholl.com/archive/2010/03/10/how-deploy-a-wcf-service-to-sharepoint-2010.aspx">http://www.chaholl.com/archive/2010/03/10/how-deploy-a-wcf-service-to-sharepoint-2010.aspx</a>    <br />    <br />I've been presenting a talk where you can start with the WCF template, then change the factory to MultipleBaseAddressWebServiceHostFactory and switch the service to a REST service.</p>  <p>&#160;</p>  <p>Finally, I sat down and created a Project Item template for SharePoint.&#160; With examples on how to create both a GET and a POST method in REST service.</p>  <p>&#160;</p>  <h3>Download:</h3>  <ul>   <li><a title="http://johnliu.net/storage/Rest.zip" href="http://johnliu.net/storage/Rest.zip">http://johnliu.net/storage/Rest.zip</a></li> </ul>  <p>&#160;</p>  <h3>Install:</h3>  <ul>   <li><em>You may need to unblock this file if you download it from IE</em></li>    <li>Copy the file to \Documents\Visual Studio 2010\Templates\ItemTemplates\Rest.zip</li>    <li>Close / Restart VS.NET </li> </ul>  <p>&#160;</p>  <h3>Use:</h3>  <ol>   <li>Create a blank SharePoint Farm solution.&#160; Services can't be deployed as Sandbox.     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061397" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061398" width="603" height="477" /></a>      <br /><strong>Figure: Create a SharePoint Farm solution.&#160; </strong>      <br /></li>    <li>Add new Project Item, the template does NOT appear under the SharePoint group currently.&#160; So you'll need to search for it.&#160; Will be fixed... &quot;Soon&quot;.&#160; Give it a nice name.     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061400" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061402" width="820" height="531" /></a>      <br /><strong>Figure: Search for the template and use it to create a REST service </strong>      <br /></li>    <li>These files are created:     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061403" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061405" width="240" height="227" /></a>      <br /><strong>Figure: My RestService1</strong>      <br />      <br /></li>    <li>The IRestService1.cs interface gives you the definition of your REST service methods.&#160; I've provided a GET and a POST operation.     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061407" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061408" width="648" height="183" /></a>      <br /><strong>Figure: GET, and POST</strong>      <br /></li>    <li>You should also add a CKS WCF Service     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061410" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061412" width="819" height="527" /></a>      <br /></li>    <li>The solution should look like this:     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061414" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061416" width="251" height="280" /></a>      <br /><strong>Figure: OK, we have a REST service and a WCF SOAP service.</strong>      <br />      <br />Important.&#160; CKSDEV's WCF Template hooks up token replacement for the *.svc file.&#160; You need to add this, even if you don't use it, otherwise you'll need to modify your VS.NET project file manually.&#160; You can remove this service after you've added it once.&#160; <br />      <br />I recommend you compare the difference between the CKSDEV WCF SOAP service and the REST Service.      <br /></li>    <li>Deploy!&#160; <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061419" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061420" width="501" height="298" /></a>      <br /><strong>Figure: I LOVE Deploy from VS.NET 2010</strong>      <br /></li>    <li>Open a browser, go to:      <br /><a href="http://server/_vti_bin/SharePointProject1/RestService1.svc/GetItem/1">http://server/_vti_bin/SharePointProject1/RestService1.svc/GetItem/1</a>      <br />      <br />You should get:      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061422" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061423" width="851" height="65" /></a>      <br />      <br /></li>    <li>The returned content type is unrecognized by Internet Explorer, so it's prompting you to save it.     <br />Save this, and open it in notepad.       <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061424" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061425" width="215" height="103" /></a>      <br /><strong>Figure: Haha!&#160; JSON'ed HelloWorld Blob object returned from the server!</strong>      <br />      <br /></li>    <li>In IE Developer Toolbar, you can watch the network traffic     <br />This particular request took 31ms and sent 463 bytes!      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061426" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061428" width="758" height="186" /></a>      <br /><strong>Figure: Extremely fast and efficient way to talk to SharePoint.</strong></li> </ol>  <p>&#160;</p>  <p>&#160;</p>  <h3>If you see this error:</h3>  <blockquote>   <p>     <br />Error</p>    <p>The type 'SharePointProject1.RestService1, $SharePoint.Project.AssemblyFullName$', provided as the Service attribute value in the ServiceHost directive could not be found.</p> </blockquote>  <p>   <br />This is because VS.NET does not perform Token Replacement for the *.svc file by default.&#160; There are a few ways to fix this.</p>  <ol>   <li>The simplest way is to add a CKSDEV WCF Service Project Item.&#160; You can remove it afterwards.     <br /></li>    <li>Alternatively, you can edit your project file, you need to find this, and add <strong>svc;</strong>      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061429" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061430" width="896" height="284" /></a>      <br />      <br />Reload your project      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061431" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061432" width="560" height="166" /></a>      <br /></li> </ol>  <p>   <br /></p>  <h3>Minor issues need fix... one day:</h3>  <p>Minor Problems:</p>  <ol>   <li>Project Item doesn't appear under SharePoint Group     <br />To properly create SharePoint Project Items, I need to define a proper .spdata file - this requires an additional project to declare a new SharePoint Project Item type.&#160; <br />This will also allow me to specify an ICON to use in the solution, instead of this silly red <a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061433" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint---here-is-a-REST-service-Proj_2C0-?fileId=16061434" width="109" height="28" /></a> looking icon.      <br /></li>    <li>Not properly set up TokenReplacementFileExtension     <br />The project will also allow me to hook into the project item wizard and link up TokenReplacementFileExtension for svc.      <br /></li>    <li>Need custom code...     <br />Custom code requires signed assemblies. Annoying.      <br /></li>    <li>Or, preferably, I clean up the template a bit more and submit it to CKSDEV, which has most of these facilities already built in.&#160; </li> </ol>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-14600197.xml</wfw:commentRss></item><item><title>InfoPath - check leap year using expression</title><category>InfoPath</category><category>SharePoint</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Wed, 11 Jan 2012 17:17:00 +0000</pubDate><link>http://johnliu.net/blog/2012/1/11/infopath-check-leap-year-using-expression.html</link><guid isPermaLink="false">358543:3878987:14530984</guid><description><![CDATA[<p>&#160;</p>  <p>This is a fun one.</p>  <ol>   <li>Use the undocumented <a href="http://msdn.microsoft.com/en-US/library/ms256474(v=VS.80).aspx">msxsl:utc</a> function, which checks / converts a date into a normalized representation.       <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---check-leap-year-using-express_D0FC-?fileId=15975242" rel="lightbox"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---check-leap-year-using-express_D0FC-?fileId=15975244" width="244" height="141" /></a>       <br />      <br /></li>    <li>So, what will happen if I test it with with a garbage date, say, the 29th of February of 2001, which isn't a leap year?      <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---check-leap-year-using-express_D0FC-?fileId=15975246" rel="lightbox"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---check-leap-year-using-express_D0FC-?fileId=15975247" width="244" height="147" /></a>       <br /></li>    <li>So just check if the result of the utc function returns empty string or not.      <br /></li> </ol>  <h2>Expression</h2>  <p>msxsl:utc(concat(my:year, &quot;-02-29&quot;)) != &quot;&quot;</p>  <ol>    </ol>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-14530984.xml</wfw:commentRss></item><item><title>Pasting pictures from clipboard to SharePoint in browser, via Silverlight 5</title><category>SharePoint</category><category>Silverlight</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Mon, 09 Jan 2012 17:09:05 +0000</pubDate><link>http://johnliu.net/blog/2012/1/9/pasting-pictures-from-clipboard-to-sharepoint-in-browser-via.html</link><guid isPermaLink="false">358543:3878987:14505464</guid><description><![CDATA[<p>Silverlight 5 was quietly released to the world to very little fanfare, considering the looming Windows 8 launch with WinRT next year, and the world (at least, Microsoft)'s shift to HTML5.</p>  <p>Still, there are a few gems in this version over Silverlight 4, in particular, you can now run <strong>trusted mode in browser</strong>, and trusted mode now has access to <strong>platform invoke</strong>.</p>  <p>That's right, repeat after me: <strong>Silverlight</strong>, <strong>in browser</strong>, <strong>unmanaged code</strong>.</p>  <p>And I just happened to have the perfect problem I've been wanting to solve forever.</p>  <p>&#160;</p>  <h2>Problem</h2>  <p>One thing that has always peeved me when using the Rich HTML control in SharePoint is when it comes to imbedding images.&#160; You can't easily add a picture to your Rich HTML, you need to open a different browser window, upload the picture, then find a link to that picture and insert it back in the HTML.</p>  <blockquote>   <h4>CTRL-V</h4> </blockquote>  <p>Wouldn't it be nice if you could just paste a picture directly to SharePoint, like you could in Word, or Windows Live Writer.&#160; The end user doesn't need to figure out where the picture will go.&#160; SharePoint will do that.&#160; Such a thing isn't possible with mere HTML since it doesn't support access to binary clipboard, but with Silverlight 5 we can now provide a solution.</p>  <p>&#160;</p>  <p>&#160;</p>  <h2>Steps </h2>  <ol>   <li>Configure in browser trusted mode </li>    <li>Setting up Silverlight with native p/invoke calls to access the clipboard </li>    <li>Using GDI to convert clipboard bitmap to a temporary PNG image file </li>    <li>Upload PNG to SharePoint, using SharePoint client object model </li>    <li>Insert HTML image reference in Silverlight Rich Text editor </li>    <li>Update SharePoint page content from Silverlight Rich Text editor </li> </ol>  <p>&#160;</p>  <p>&#160;</p>  <h2>1. Configure In Browser Trusted Mode</h2>  <p>The easy step.&#160; Head over to Silverlight project properties in VS.NET</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945557" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945558" width="644" height="441" /></a></p>  <p><strong>Figure: Silverlight 5 specialty, elevated trust running in-browser.</strong>     <br /></p>  <h2>2. Setting up Silverlight with native p/invoke and talk to the clipboard natively.</h2>  <p>&#160;</p>  <p>internal class Native    <br />{     <br />&#160;&#160;&#160; [DllImport(&quot;user32.dll&quot;, EntryPoint = &quot;CloseClipboard&quot;, SetLastError = true)]     <br />&#160;&#160;&#160; [return: MarshalAs(UnmanagedType.Bool)]     <br />&#160;&#160;&#160; public static extern bool CloseClipboard();</p>  <p>&#160;&#160;&#160; [DllImport(&quot;user32.dll&quot;, EntryPoint = &quot;GetClipboardData&quot;, SetLastError = true)]    <br />&#160;&#160;&#160; public static extern IntPtr GetClipboardData(ClipboardFormat uFormat);</p>  <p>&#160;&#160;&#160; [DllImport(&quot;user32.dll&quot;, EntryPoint = &quot;IsClipboardFormatAvailable&quot;, SetLastError = true)]    <br />&#160;&#160;&#160; [return: MarshalAs(UnmanagedType.Bool)]     <br />&#160;&#160;&#160; public static extern bool IsClipboardFormatAvailable(ClipboardFormat format);</p>  <p>&#160;&#160;&#160; [DllImport(&quot;user32.dll&quot;, EntryPoint = &quot;OpenClipboard&quot;, SetLastError = true)]    <br />&#160;&#160;&#160; [return: MarshalAs(UnmanagedType.Bool)]     <br />&#160;&#160;&#160; public static extern bool OpenClipboard([In] IntPtr hWndNewOwner);</p>  <p>}</p>  <p>&#160;</p>  <p>In my paste function:</p>  <p>private void Paste()    <br />{     <br />&#160;&#160;&#160; if (!Application.Current.HasElevatedPermissions)     <br />&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; MessageBox.Show(&quot;No Elevated Permissions - can't do p/invoke :'-(&quot;);     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return;     <br />&#160;&#160;&#160; }     <br />&#160;&#160;&#160; IntPtr p = IntPtr.Zero;</p>  <p>&#160;&#160;&#160; bool opened = Native.OpenClipboard(p);</p>  <p>&#160;&#160;&#160; if (!opened)&#160; <br />&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return; //unhappy     <br />&#160;&#160;&#160; }</p>  <p>&#160;&#160;&#160; try {</p>  <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (Native.IsClipboardFormatAvailable(ClipboardFormat.CF_BITMAP))    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; IntPtr p4 = Native.GetClipboardData(ClipboardFormat.CF_BITMAP);</p>  <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // GASP.&#160; We have a pointer to our bitmap!    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }     <br />&#160;&#160;&#160; }     <br />&#160;&#160;&#160; finally&#160; <br />&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; Native.CloseClipboard();     <br />&#160;&#160;&#160; }</p>  <p>}</p>  <p>&#160;</p>  <h2>3. Using GDI to convert clipboard bitmap to a temporary PNG image file </h2>  <p>It's awesome we have a pointer, but what do we do with it?&#160; This next part eluded me for months, I had to stop work, and go on the Internet to ask for help.&#160; 3 months later, at the end of 2011 a <a href="http://imagetools.codeplex.com/discussions/273754">reply</a> came through.&#160; Use GDI+ to convert the pointer to a file!&#160; Genius!&#160; Bravo!</p>  <p>Note that in the GDI+ GdipSaveImageToFile call, I use the PNG Encoder - so the bitmap is saved in PNG format in my temporary file.</p>  <p>Oh, right, more native p/invoke, different DLL this time.</p>  <p>internal class Native    <br />{</p>  <p>&#160;&#160; ... &lt;snip earlier clipboard p/invoke&gt;    <br />&#160;&#160;&#160; [DllImport(&quot;gdiplus.dll&quot;, CharSet = CharSet.Unicode)]     <br />&#160;&#160;&#160; public static extern int GdipCreateBitmapFromHBITMAP(IntPtr hbitmap, IntPtr hpalette, out IntPtr bitmap);     <br />&#160;&#160;&#160; [DllImport(&quot;gdiplus.dll&quot;, CharSet = CharSet.Unicode)]     <br />&#160;&#160;&#160; public static extern int GdipSaveImageToFile(IntPtr image, string filename, ref Guid classId, IntPtr encoderParams);     <br />&#160;&#160;&#160; [DllImport(&quot;gdiplus.dll&quot;, CharSet = CharSet.Unicode, ExactSpelling = true)]     <br />&#160;&#160;&#160; public static extern long GdiplusStartup(out IntPtr token, ref GdiplusStartupInput gdiplusStartupInput, out IntPtr gdiplusStartupOutput);     <br />&#160;&#160;&#160; [DllImport(&quot;gdiplus.dll&quot;)]     <br />&#160;&#160;&#160; public static extern void GdiplusShutdown(IntPtr token);     <br />}</p>  <p>&#160;</p>  <p>IntPtr gdipToken = IntPtr.Zero; ;    <br />string fileName = string.Empty;</p>  <p>try    <br />{</p>  <p>&#160;&#160;&#160; IntPtr gdiplusStartupOutput;    <br />&#160;&#160;&#160; GdiplusStartupInput input = new GdiplusStartupInput(1);     <br />&#160;&#160;&#160; long num0 = Native.GdiplusStartup(out gdipToken, ref input, out gdiplusStartupOutput);</p>  <p>&#160;&#160;&#160; IntPtr zero = IntPtr.Zero;    <br />&#160;&#160;&#160; IntPtr palette = IntPtr.Zero;</p>  <p>&#160;&#160;&#160; int num = Native.GdipCreateBitmapFromHBITMAP(p4, palette, out zero);    <br />&#160;&#160;&#160; if (num != 0)     <br />&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return;     <br />&#160;&#160;&#160; }</p>  <p>&#160;&#160;&#160; // JPG Encoder {557CF401-1A04-11D3-9A73-0000F81EF32E}    <br />&#160;&#160;&#160; // PNG Encoder {557CF406-1A04-11D3-9A73-0000F81EF32E}     <br />&#160;&#160;&#160; Guid classId = Guid.Parse(&quot;{557CF406-1A04-11D3-9A73-0000F81EF32E}&quot;);</p>  <p>&#160;&#160;&#160; fileName = System.IO.Path.GetTempFileName();</p>  <p>&#160;&#160;&#160; int img = Native.GdipSaveImageToFile(zero, fileName, ref classId, palette);    <br />&#160;&#160;&#160; if (img != 0)     <br />&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return;     <br />&#160;&#160;&#160; }     <br />}     <br />finally     <br />{     <br />&#160;&#160;&#160; Native.GdiplusShutdown(gdipToken);     <br />}</p>  <p>&#160;</p>  <h2>4. Upload PNG to SharePoint, using SharePoint client object model </h2>  <p>&#160;</p>  <p>using(FileStream fs = File.OpenRead(fileName))    <br />{     <br />&#160;&#160;&#160; SP.ClientContext ctx = SP.ClientContext.Current;</p>  <p>&#160;&#160;&#160; SP.Web web = ctx.Web;    <br />&#160;&#160;&#160; SP.List library = web.Lists.GetByTitle(&quot;Images&quot;);</p>  <p>&#160;&#160;&#160; byte[] content = new byte[fs.Length];    <br />&#160;&#160;&#160; var newFile = new SP.FileCreationInformation();     <br />&#160;&#160;&#160; int dummy = fs.Read(content, 0, (int)fs.Length);     <br />&#160;&#160;&#160; newFile.Content = content;     <br />&#160;&#160;&#160; newFile.Url = string.Format(&quot;paste_{0}.png&quot;, DateTime.Now.Ticks);     <br />&#160;&#160;&#160; var uploadFile = library.RootFolder.Files.Add(newFile);     <br />&#160;&#160;&#160; ctx.Load(uploadFile);     <br />&#160;&#160;&#160; ctx.ExecuteQueryAsync(     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; delegate {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.Dispatcher.BeginInvoke(() =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {</p>  <p>// update our rich text editor in step 5!    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; },     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; delegate {&#160; // our code don't fail!&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; });</p>  <p>}</p>  <p>&#160;</p>  <h2>5. Insert HTML image reference in Silverlight HTML Text editor </h2>  <p>I'm using the wonderful <a href="http://www.vectorlight.net/silverlight.aspx">free VectorLight.NET Liquid HTML Editor control</a>.&#160; Need free registration.&#160; Supports converting between Rich XAML and HTML formats.&#160; Here I'm inserting a &lt;Xaml&gt;&lt;Image /&gt;&lt;/Xaml&gt;</p>  <p>&#160;</p>  <p>ctx.ExecuteQueryAsync(    <br />&#160;&#160;&#160; delegate {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.Dispatcher.BeginInvoke(() =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.listBox1.Items.Add(uploadFile.ServerRelativeUrl);</p>  <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; InlineUIContainer container = new InlineUIContainer();    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; Uri server = new Uri(ctx.Url);     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; string path = string.Format(&quot;{0}://{1}{2}&quot;, server.Scheme, server.Host, uploadFile.ServerRelativeUrl);     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.richTextBox1.Insert(string.Format(&quot;&lt;Xaml&gt;&lt;Image Source=\&quot;{0}\&quot; /&gt;&lt;/Xaml&gt;&quot;, path));     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; });     <br />&#160;&#160;&#160; },     <br />&#160;&#160;&#160; delegate {     <br />&#160;&#160;&#160; <br />&#160;&#160;&#160; });</p>  <h2>5.1 Pictures - just to prove it works</h2>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945561" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945563" width="614" height="589" /></a></p>  <p><strong>Figure: Pasting picture into HTML Editor within Silverlight.</strong></p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945564" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945566" width="888" height="538" /></a></p>  <p><strong>Figure: My SharePoint image library, filled with pasted images :-)</strong></p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945568" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945569" width="417" height="326" /></a></p>  <p><strong>Figure: Dumping Editor's HTML to MessageBox - you can see the &lt;img&gt; HTML is inserted properly.</strong></p>  <p>&#160;</p>  <h2>6. Update SharePoint page content from Silverlight Rich Text editor </h2>  <ol><!--EndFragment--></ol>  <p>This part is the most ugly bit of the code.&#160; Heavily nested since I keep using anonymous delegates, and it's pretty late so I'm not going to clean it up tonight.</p>  <p>The Save button click.</p>  <p>   <br />private void buttonSave_Click(object sender, RoutedEventArgs e)     <br />{     <br />&#160;&#160;&#160; var ctx = SP.ClientContext.Current;     <br />&#160;&#160;&#160; var library = ctx.Web.Lists.GetByTitle(&quot;Site Pages&quot;);     <br />&#160;&#160;&#160; var items = library.GetItems(SP.CamlQuery.CreateAllItemsQuery());</p>  <p>&#160;&#160;&#160; var filepath = this.autoCompleteBox1.Text;&#160; // I store a list of pages in the dropdown...    <br />&#160;&#160;&#160; ctx.Load(items);</p>  <p>&#160;&#160;&#160; ctx.ExecuteQueryAsync(    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; delegate     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // switch back to UI thread     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.Dispatcher.BeginInvoke(() =&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; SP.ListItem page = null;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; foreach (var item in items)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // super ugly code - should filter the files in the CamlQuery above - but too tired to write Caml     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (item[&quot;FileLeafRef&quot;].ToString() == filepath)     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; page = item;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; page[&quot;WikiField&quot;] = this.richTextBox1.HTML;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; page.Update();&#160; // update SPListItem, then ExecuteQuery to push the update back through ClientService.svc     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; ctx.ExecuteQueryAsync(     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; delegate     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // switch back to UI thread</p>  <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; this.Dispatcher.BeginInvoke(() =&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // refresh browser     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; HtmlPage.Document.Submit();     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; },     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; delegate { });     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; });     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; },     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; delegate     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; });     <br />}     <br /></p>  <p>&#160;</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945570" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945571" width="590" height="660" /></a></p>  <p><strong>Figure: The Silverlight webpart pushing HTML back into a Wikipage</strong></p>  <p>&#160;</p>  <p>&#160;</p>  <p>There are some notes on security, which I leave right at the end, but this is important.</p>  <h2>Trusted mode / In Browser</h2>  <ol>   <li>When running under <a href="http://localhost/">http://localhost/</a> SL5 skips checking this (easy for debug) </li>    <li>For normal operation, requires Silverlight XAP file to be signed with a code trust certificate.&#160; You can generate one yourself, just make sure you add it to the right store.      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945572" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945573" width="507" height="455" /></a>       <br /><strong>Figure: Yes... Trusted Root Certification Authorities.&#160; Yep sounds about right!</strong>       <br /></li>    <li>And requires a registry key to be present for Silverlight      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945574" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-Pasting-pictures-to-SharePoint-in-browse_9696-?fileId=15945575" width="688" height="246" /></a>       <br /><strong>FIgure: OMG #1, Registry, really!?</strong>       <br /></li>    <li>You will need to deploy this to your uses via a group policy, or a click once application if your user has permissions to write to their own registry.&#160; </li> </ol>  <p>This bit I think is the part that makes the solution safe, but also very difficult to deploy.&#160; But if you want the nice editing experience with paste functionality, here you go!</p>  <p>&#160;</p>  <p>&#160;</p>  <h2>Downloads</h2>  <ul>   <li>XAP file (Contact me for the XAP file - it needs a bit of cleaning up, and I need to test the certificate) </li>    <li>SPClip cert </li> </ul>  <p>&#160;</p>  <p>And here we go, first big post of the year.&#160; Have a great 2012 everyone!</p>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-14505464.xml</wfw:commentRss></item><item><title>The blogger's eternal struggle for blog reader comments</title><category>rant</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Thu, 15 Dec 2011 13:24:34 +0000</pubDate><link>http://johnliu.net/blog/2011/12/15/the-bloggers-eternal-struggle-for-blog-reader-comments.html</link><guid isPermaLink="false">358543:3878987:14129552</guid><description><![CDATA[<p>Sometimes, a rant (and warning, this particular blog post can only be classified as a rant) is just too long to be said in a 140 character tweet.</p>  <p>&#160;</p>  <h3>A simple wish, in my simple world</h3>  <p>I have always told myself that when I write on this blog, I did it for fun, to brag about what I've been up to, to remember what I did, and if by sheer luck help other people, that's an awesome bonus.</p>  <p>Increasingly though, and I'll be very honest, I think I do this for the <strong><em><font color="#ffc000"><u>warm fuzzy feeling</u></font></em></strong> when people leave a nice comment.</p>  <p>I really like comments.&#160; I like to know what people think of what I wrote.&#160; I want to know if they think I didn't help them - may be they were searching for one thing and got a different answer.&#160; I want to know if they think my writing style needs work.&#160; May be I need a spellchecker.</p>  <p>I crave for that feedback.&#160; I'm over the moon when I get it.</p>  <p>I'm bothered when I see lots of traffic, but no comments.&#160; Am I doing something wrong, am I not helping people, do people think I just blubber about rubbish.&#160; People are searching for answers to their problems, did they not find it here?</p>  <p>&#160;</p>  <p>And that's just the beginning of my problems...</p>  <h3>Enter the giant social networks</h3>  <p>And their walled gardens.</p>  <p>The best thing about the social networks is that it encourages people to be chatty, and comment on things.&#160; The worse thing about it is that it's all hidden behind walled gardens and I can't see them.</p>  <p>I love talking to my friends on Facebook and Twitter.&#160; But sorry, conversations in those walled gardens doesn't return to the original content creator.&#160; Actually, what's happening is that people are gossips behind my back!&#160; Preposterous! </p>  <p>&#160;</p>  <p>I really gave it some thought...</p>  <h3>A good idea starts with me taking a small step</h3>  <p>I realized what I can do, and this is more a behaviour change than something technical.&#160; I'm going to be more social, and actually make an effort to always leave a comment on any blog that I visit and has helped me.</p>  <p>If I think the content can be improved, I will suggest it.&#160; If I have more to add, I will blog and link back, if I just want to say thank you, I will do so, because I know it always gave me a warm feeling when others did it to me, and I should give that back to other people.</p>  <p>Love the blogging and long live the bloggers!</p>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-14129552.xml</wfw:commentRss></item><item><title>SharePoint - disguise your long running AJAX calls</title><category>SharePoint</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Wed, 30 Nov 2011 07:02:38 +0000</pubDate><link>http://johnliu.net/blog/2011/11/30/sharepoint-disguise-your-long-running-ajax-calls.html</link><guid isPermaLink="false">358543:3878987:13914270</guid><description><![CDATA[<p>I have to confess I haven't had so much laugh in SharePoint for a long time.</p>  <h3>OK, here's the problem:</h3>  <ol>   <li>I'm calling a custom REST service that I've developed - the REST service checks a bunch of database records, as well as creating a new site and activate a number of features on that site.&#160; </li>    <li>Basically, it takes a while to run.&#160; May be around 15 seconds.</li> </ol>  <p>&#160;</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-0ef443bb245e_EF20-?fileId=15355187" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-0ef443bb245e_EF20-?fileId=15355188" width="324" height="164" /></a>    <br />Figure: Once you click this link it gets busy on the server.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-0ef443bb245e_EF20-?fileId=15355189" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-0ef443bb245e_EF20-?fileId=15355190" width="314" height="168" /></a>    <br />Figure: Once it's clicked, I disable the link    <br /></p>  <h3>Put up a dialog to tell the user to wait</h3>  <p>The first thing we should do is put up a dialog to tell the user hey something's happening.</p>  <p>Waldek Mastykarz has an awesome article on how to do most of this, so I won't type out his code.&#160; <a href="http://blog.mastykarz.nl/sharepoint-2010-ui-tip-non-obtrusive-progress-messages/">http://blog.mastykarz.nl/sharepoint-2010-ui-tip-non-obtrusive-progress-messages/</a>    <br /></p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-0ef443bb245e_EF20-?fileId=15355191" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-0ef443bb245e_EF20-?fileId=15355192" width="365" height="161" /></a>&#160; <br />Figure: Here's my blocking dialog.&#160; No close box.&#160; It spins for about 15 seconds and then disappears when the AJAX call receives a success response.</p>  <p>&#160;</p>  <p>But waiting for 15 seconds really gets boring.</p>  <h3>You realize that you must use better messages, and update it as you wait.&#160; </h3>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-0ef443bb245e_EF20-?fileId=15355193" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-0ef443bb245e_EF20-?fileId=15355194" width="371" height="146" /></a></p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-0ef443bb245e_EF20-?fileId=15355195" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-0ef443bb245e_EF20-?fileId=15355196" width="352" height="131" /></a></p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-0ef443bb245e_EF20-?fileId=15355197" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-0ef443bb245e_EF20-?fileId=15355198" width="350" height="138" /></a></p>  <p>&#160;</p>  <p>Here's the javascript code.</p>  <p>&#160;</p>  <p>&#160;&#160;&#160; var msgs = [   <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;Calculating web paths&quot;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;Negotiating with site collection&quot;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;Creating empty site template&quot;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;Activating Features&quot;,     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;Synchronizing template&quot;,     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;Setting up form libraries&quot;,     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;Copying pages&quot;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;Configuring webparts&quot;,    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &quot;Chasing chickens&quot;];&#160;&#160;&#160; <br />&#160;&#160;&#160; <br />&#160;&#160;&#160; var p = function(){    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (waitDialog) {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var msg = msgs[Math.floor(Math.random()*msgs.length)];    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; waitDialog.get_html().getElementsByTagName('TD')[1].innerHTML = msg;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; setTimeout(p, 1000);    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }    <br />&#160;&#160;&#160; };    <br />&#160;&#160;&#160; setTimeout(p,1000);    <br /></p>  <p>Create an array of status messages - these (aside from the chicken) are really what the REST service is doing.&#160; I also create a function p, which choses a random message and updates the waitDialog.&#160; Repeat every second.&#160; When the AJAX call completes, it destroys the waitDialog, and set it to null.&#160; This stops the setTimeout loop.</p>  <p>&#160;</p>  <h3>Some sort of magic happened</h3>  <p>Suddenly, because things are updating on screen, the process doesn't seem long at all.&#160; You click it, a few messages flash past, before you know it the site's created and ready to go.</p>  <p>So there you have it, the trick really is just a clever disguise.&#160; </p>  <h3>You show users random messages and distract them from the fact that they have to wait for 15 seconds.</h3>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-13914270.xml</wfw:commentRss></item><item><title>InfoPath - removing newline (CRLF) using rules</title><category>InfoPath</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Tue, 22 Nov 2011 23:01:35 +0000</pubDate><link>http://johnliu.net/blog/2011/11/22/infopath-removing-newline-crlf-using-rules.html</link><guid isPermaLink="false">358543:3878987:13832472</guid><description><![CDATA[<p>&#160;</p>  <ol>   <li>In InfoPath (and in Windows in general), a newline is two characters \r\n (carriage return, followed by a newline character). </li>    <li>You can't easily use \r or \n within InfoPath rules, since the XML is escaped into \\r and \\n defeating your intention. </li>    <li>First, add a characters secondary data source: <a href="http://johnliu.net/blog/2011/10/12/infopath-an-example-of-using-an-xml-file-for-special-charact.html">Add an external XML file for characters</a>       <br />You should get this secondary data source with the special characters we need.      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---removing-newline-CRLF-using-r_8AD6-?fileId=15252716" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---removing-newline-CRLF-using-r_8AD6-?fileId=15252717" width="210" height="220" /></a>       <br /></li>    <li>On the field that you want to remove newlines, add a changed rule:      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---removing-newline-CRLF-using-r_8AD6-?fileId=15252718" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---removing-newline-CRLF-using-r_8AD6-?fileId=15252720" width="494" height="305" /></a>       <br />      <br />The translate rule is:       <br />translate(., @crlf, &quot;&quot;)       <br />or expanded xpath:       <br />translate(., xdXDocument:GetDOM(&quot;characters&quot;)/lookups/characters/@crlf, &quot;&quot;)       <br />      <br />use select field and change the datasource to characters.      <br /></li>    <li>To prevent this rule from running into infinite loop, set a condition:      <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---removing-newline-CRLF-using-r_8AD6-?fileId=15252721" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---removing-newline-CRLF-using-r_8AD6-?fileId=15252723" width="623" height="131" /></a>       <br />      <br />The expression is:       <br />contains(., xdXDocument:GetDOM(&quot;characters&quot;)/lookups/characters/@crlf)       <br /></li>    <li>Result:      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---removing-newline-CRLF-using-r_8AD6-?fileId=15252724" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---removing-newline-CRLF-using-r_8AD6-?fileId=15252725" width="228" height="462" /></a>&#160; <br /></li> </ol>  <h3>Test it! </h3>  <p>   <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---removing-newline-CRLF-using-r_8AD6-?fileId=15252726" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---removing-newline-CRLF-using-r_8AD6-?fileId=15252727" width="293" height="114" /></a>     <br />Test typing something with newline     <br />    <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---removing-newline-CRLF-using-r_8AD6-?fileId=15252728" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---removing-newline-CRLF-using-r_8AD6-?fileId=15252729" width="300" height="64" /></a>     <br />Rule runs and removes any new line characters </p>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-13832472.xml</wfw:commentRss></item><item><title>InfoPath - Concat SharePoint list with the Eval function (aka Voodoo)</title><category>InfoPath</category><category>SharePoint</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Fri, 11 Nov 2011 13:19:54 +0000</pubDate><link>http://johnliu.net/blog/2011/11/11/infopath-concat-sharepoint-list-with-the-eval-function-aka-v.html</link><guid isPermaLink="false">358543:3878987:13679672</guid><description><![CDATA[<p>&#160;</p>  <p>It really can't hurt to play with the crazy XPath capabilities within InfoPath.&#160; This is documented in many places, starting: </p>  <p><a href="http://blogs.msdn.com/b/infopath/archive/2006/04/05/569338.aspx">http://blogs.msdn.com/b/infopath/archive/2006/04/05/569338.aspx</a></p>  <p>Which offered possibly the best explanation of how this technique with Eval() actually works.&#160; I prefer to remembered this as <strong>PURE VOODOO</strong>.</p>  <p>&#160;</p>  <h3>1. Create our SharePoint list</h3>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-b75f8b433c7d_124-?fileId=15077679" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-b75f8b433c7d_124-?fileId=15077680" width="230" height="220" /></a></p>  <p>&#160;</p>  <h3>2. Create a secondary data connection to the list</h3>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-b75f8b433c7d_124-?fileId=15077681" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-b75f8b433c7d_124-?fileId=15077683" width="473" height="349" /></a></p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-b75f8b433c7d_124-?fileId=15077684" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-b75f8b433c7d_124-?fileId=15077685" width="355" height="349" /></a></p>  <p>&#160;</p>  <h3>3. Drag the dataFields section into the form, to create a common binding parent</h3>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-b75f8b433c7d_124-?fileId=15077686" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-b75f8b433c7d_124-?fileId=15077688" width="639" height="209" /></a></p>  <p>This step makes step 4 a lot easier, since the Eval <em>loop</em> is relative and works on the repeating section inside the dataFields section.</p>  <p>&#160;</p>  <h3>4. Add expression box within this Section</h3>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-b75f8b433c7d_124-?fileId=15077689" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-b75f8b433c7d_124-?fileId=15077690" width="603" height="268" /></a></p>        <p>The Expression is:   <br />xdMath:Eval(xdMath:Eval(d:SharePointListItem_RW, 'concat(d:Title, &quot;:&quot;)'), &quot;..&quot;)</p>  <p>&#160;</p>  <h3>5. Result: </h3>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-b75f8b433c7d_124-?fileId=15077691" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-b75f8b433c7d_124-?fileId=15077694" width="475" height="337" /></a></p>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-13679672.xml</wfw:commentRss></item><item><title>InfoPath - managing lots of tooltip in your browser form</title><category>InfoPath</category><category>SharePoint</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Thu, 10 Nov 2011 14:02:15 +0000</pubDate><link>http://johnliu.net/blog/2011/11/10/infopath-managing-lots-of-tooltip-in-your-browser-form.html</link><guid isPermaLink="false">358543:3878987:13666046</guid><description><![CDATA[<p>This is an idea that I've been brooding for a long time.&#160; Finally got a prototype implemented.</p>  <p>&#160;</p>  <p>We have a complicated looking InfoPath form.&#160; We've always wanted to have lots of help (i) tooltips.&#160; The picture below alone has 24 information tips.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061396" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061397" width="494" height="378" /></a></p>  <p>&#160;</p>  <p>The original plan is to use an Picture button, set the image to the image resource (so that they all share the same resource), and manually add tooltips to each button.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061398" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061402" width="410" height="175" /></a></p>  <p>This approach works OK, but is very tedious.&#160; Each one of our views are massive, and we have about 10 of them.&#160; Some fields re-appear on different views and need to have the same tooltip.&#160; This is also not very manageable - we can't modify the tooltip easily without republishing the InfoPath form.</p>  <p>&#160;</p>  <p>An idea begin brewing by combining an external XML file along with the Rich HTML control, something that I've experimented recently.</p>  <p><a href="http://johnliu.net/blog/2011/5/30/infopath-2010-embed-html-for-rich-and-web-forms.html">http://johnliu.net/blog/2011/5/30/infopath-2010-embed-html-for-rich-and-web-forms.html</a>     <br /><a href="http://johnliu.net/blog/2011/10/12/infopath-an-example-of-using-an-xml-file-for-special-charact.html">http://johnliu.net/blog/2011/10/12/infopath-an-example-of-using-an-xml-file-for-special-charact.html</a></p>  <p>&#160;</p>  <h3>Idea!</h3>  <ol>   <li>Produce an XML file that has all our tooltips. </li>    <li>Store this file in SharePoint </li>    <li>In InfoPath, connect to this XML file as an external datasource, always load it from server </li>    <li>Bind the XML fields to Rich HTML controls </li> </ol>  <p>&#160;</p>  <h3>1. My tooltip XML file.&#160; </h3>  <p>My XML file, with 2 entries in it for &quot;office&quot; and &quot;state&quot;.&#160; </p>  <p>Note the content of the two entries is essentially a HTML IMG tag.&#160; With the source pointing to an image stored in SharePoint, and a tooltip.    <br /></p>  <p>&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;    <br />&lt;html&gt;     <br />&#160; &lt;office&gt;     <br />&#160;&#160; &lt;img xmlns=&quot;<a href="http://www.w3.org/1999/xhtml&quot;">http://www.w3.org/1999/xhtml&quot;</a> src=&quot;/Style Library/Images/info.png&quot; border=&quot;0&quot; title=&quot;Select the Office that will administer this project&quot; /&gt;     <br />&#160; &lt;/office&gt;     <br />&#160; &lt;state&gt;     <br />&#160;&#160;&#160; &lt;img xmlns=&quot;<a href="http://www.w3.org/1999/xhtml&quot;">http://www.w3.org/1999/xhtml&quot;</a> src=&quot;/Style Library/Images/info.png&quot; border=&quot;0&quot; title=&quot;Select the State that this project will report to&quot; /&gt;     <br />&#160; &lt;/state&gt;     <br />&lt;/html&gt;</p>  <p>&#160;</p>  <h3>2. Store this file in SharePoint</h3>  <p>I store this in SharePoint, on /Style Library/html-tooltip.xml.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061403" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061404" width="233" height="240" /></a></p>  <p>&#160;</p>  <h3>3. Add secondary data source in InfoPath</h3>  <p>Add XML datasource.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061405" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061407" width="611" height="210" /></a></p>  <p>Select &quot;Access the data from specified location&quot;</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061408" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061410" width="615" height="225" /></a></p>  <p>Always retrieve data</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061411" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061413" width="614" height="312" /></a></p>  <p>Result data connection</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061415" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061417" width="524" height="352" /></a></p>  <p>&#160;</p>  <h3>4. Bind to Rich HTML controls</h3>  <p>Switch to the secondary data source in the Fields tool pane.    <br />Drag my new entry for &quot;State&quot; with the right click contextual menu.     <br />Select Rich Text Box</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061418" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061419" width="700" height="184" /></a></p>  <p>&#160;</p>  <p>There's quite a bit of clean up to do:   <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061420" rel="lightbox"><img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061421" width="146" height="113" /></a></p>  <ul>   <li>Remove the label </li>    <li>Set the background shade to No Fill </li>    <li>Set border to 1px solid white - you must keep 1px border, otherwise when you hover over the picture the Rich Text box will shift as InfoPath adds a focus to the box.</li>    <li>Set the height and width to 25px (size of my images). </li>    <li>Select Read-Only in the ribbon      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061422" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061423" width="135" height="142" /></a></li>    <li>The result:     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061424" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061425" width="180" height="65" /></a></li> </ul>  <p>&#160;</p>  <h3>Extra Note</h3>  <p>You must show the web form Ribbon, otherwise the Rich Text is rendered differently in an iFrame, and the IMG tooltip won't show up.&#160; Sorry, this behaviour is so weird, I do have an ugly workaround but I won't publish it - really ugly.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061426" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061427" width="442" height="145" /></a></p>  <p>&#160;</p>  <h3>See it in action:</h3>        <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061428" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061429" width="299" height="81" /></a></p>  <p>&#160;</p>  <p>And if you need to change the text, open up the XML file in SharePoint designer, change it, and save the XML file again.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061430" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061431" width="525" height="50" /></a></p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061433" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---provide-lots-of-help-text_A4E4-?fileId=15061434" width="327" height="91" /></a></p>        <p>&#160;</p>  <h3>Summary</h3>  <ul>   <li>A technique to use one XML file in SharePoint to specify many HTML tooltip elements to be used within an InfoPath form</li>    <li>This allows tooltips to be updated independently of templates, and multiple elements in the InfoPath form can share and reuse the same tooltip</li> </ul>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-13666046.xml</wfw:commentRss></item><item><title>InfoPath - packaging site columns and content types</title><category>InfoPath</category><category>SharePoint</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Mon, 07 Nov 2011 23:05:41 +0000</pubDate><link>http://johnliu.net/blog/2011/11/7/infopath-packaging-site-columns-and-content-types.html</link><guid isPermaLink="false">358543:3878987:13631677</guid><description><![CDATA[<p>A discussion popped up on the InfoPath forums and I took a good stab at it.</p>  <p><a href="http://social.technet.microsoft.com/Forums/en-US/sharepoint2010customization/thread/d2982a7c-86e1-4868-864b-2fcea68274fd/">http://social.technet.microsoft.com/Forums/en-US/sharepoint2010customization/thread/d2982a7c-86e1-4868-864b-2fcea68274fd/</a></p>  <p><a href="http://www.linkedin.com/profile/view?id=22859060">Jason Li</a>&#160;</p>  <blockquote>   <p>Content Deployment between different environments (InfoPath, SharePoint Designer Workflow, Content Type) in SharePoint 2010     <br />I have read many discussions on this (or similar topic) and still would like to post this again to see if I can get real answers:</p>    <ol>     <li>I have InfoPath forms. </li>      <li>These forms are published as content types.&#160; </li>      <li>I have reusable SharePoint Designer workflows.&#160;&#160; </li>      <li>I have document libraries created to use these content types. </li>      <li>I have security groups.</li>   </ol>    <p>How do I move these things from DEV to TEST, UAT all the way into PROD.&#160; </p>    <p>As to #3:&#160; GUID is driving me crazy.</p> </blockquote>  <p>&#160;</p>  <h3>Content Type deployment across different farms</h3>  <p>The only way I have ever got all the environments to obey my command regarding content types is to use Solution Packages.</p>  <ol>   <li>Create InfoPath form in DEV, when publishing, use Content Type, and Site Columns.</li>    <li>Once the Content Type and Site Columns are created, package them into a WSP.&#160; From now on, always deploy content type and site columns using WSP.&#160; This forces All the GUIDS to be identical across all farms, which makes everything work nice.&#160; (see below for steps and pictures).</li>    <li>Reusable SharePoint designer workflows can be tied to these content type / site columns, so can document library.</li>    <li>Deploy package to TEST, you can create document libraries with feature as well, or configure them manually.&#160; I deploy InfoPath forms to TEST by publishing from InfoPath to the TEST environment, depending on whether you are doing:</li>    <ul>     <li>Site content type: publish to the destination list - it should automatically pick up the content type since the GUID are the same.&#160; Site columns will match too.</li>      <li>Central admin forms - deploy via central admin, this places the form template back in /FormServerTemplates/ on the root site, hook this back using Content Type / advanced / form template in each list.</li>   </ul> </ol>  <p>InfoPath forms always have data connections (since InfoPath can't do anything), you should convert all data connections to connection files hosted relatively on each DEV, TEST, etc. environment, this way you don't need to modify the form template, and depending which environment it's published to, it'll go and find the right sets of data.</p>  <p>&#160;</p>  <h3>Packaging InfoPath Content Type and Site Columns</h3>  <p>&#160;</p>  <p>Packaging site columns and content types are a lot easier now in SharePoint 2010 with VS.NET 2010.&#160; </p>  <p>Grab CKS extension first.   <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018642" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018645" width="644" height="216" /></a></p>  <ol>   <li>Create an empty SharePoint project on the DEV server.&#160; I've always used Farm Solutions but there's probably no harm trying Sandbox Solutions.     <br /></li>    <li>In the Server Explorer, navigate to your SharePoint DEV site.&#160; Expand the nodes and find your Content Type under the root web.&#160; Select Import Content Type to bring this definition into your SharePoint project.     <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018646" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018647" width="309" height="169" /></a>      <br /></li>    <li>This will import the content type under a feature with a default name Feature 1.&#160; Rename the feature (VS.NET will fix all the related names).     <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018648" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018649" width="243" height="224" /></a>      <br /></li>    <li>Open the feature and fix the Title as well.&#160; Notice that this feature is Web scoped.     <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018651" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018652" width="644" height="225" /></a>      <br /></li>    <li>Next, navigate in the Server Explorer to the site columns, and bring in the Site columns that was promoted from InfoPath.     <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018654" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018655" width="217" height="141" /></a>      <br /></li>    <li>This brings in two additional elements with pretty ugly GUID-names.&#160; Need to tidy this up.     <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018656" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018657" width="227" height="111" /></a>      <br /></li>    <li>Open the Elements.xml file under the two site columns, and copy the &lt;Field... /&gt; definitions.     <br />Open the Elements.xml file under the InfoPath content type, and insert the site column definitions above the content type definition.      <br />      <br />(You'll see the content type has FieldRef to the exported columns).      <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018658" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018660" width="673" height="238" /></a>      <br /></li>    <li>Build the project into a package     <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018662" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018663" width="409" height="166" /></a>      <br /></li>    <li>Ta-da!     <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018664" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-26401e9f72db_83EB-?fileId=15018665" width="597" height="38" /></a></li> </ol>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-13631677.xml</wfw:commentRss></item><item><title>SharePoint Saturday Melbourne update</title><category>SharePoint</category><category>code</category><dc:creator>JohnLiu.NET</dc:creator><pubDate>Sat, 22 Oct 2011 12:03:20 +0000</pubDate><link>http://johnliu.net/blog/2011/10/22/sharepoint-saturday-melbourne-update.html</link><guid isPermaLink="false">358543:3878987:13414884</guid><description><![CDATA[<p>I had a pleasure of flying down and presenting at the SharePoint Saturday Melbourne event.&#160; Had a great time, met many new people and presented my talk on Custom Rest Services and jQuery AJAX, hope you guys enjoyed it.</p>  <p>Highlights for the presentation were the number of people that put up their hands saying they will try this in their environment - that was very encouraging - it's all fairly simple when you look at the result in small chunks.&#160; Thank you guys.</p>  <p>&#160;</p>  <p>The links to the PowerPoint presentation and the demo solution are here:</p>  <ul>   <li><a title="http://johnliu.net/storage/SharePoint%20REST%20and%20jQuery3.pptx" href="http://johnliu.net/storage/SharePoint%20REST%20and%20jQuery3.pptx">http://johnliu.net/storage/SharePoint%20REST%20and%20jQuery3.pptx</a></li>    <li><a title="http://johnliu.net/storage/SPGSvcWp.zip" href="http://johnliu.net/storage/SPGSvcWp.zip">http://johnliu.net/storage/SPGSvcWp.zip</a></li> </ul>  <p>&#160;</p>  <p>Because I ran out of time (sorry), the bits that I missed were:</p>  <ul>   <li>The 3rd service factory in SharePoint 2010 is for the DataService, allowing you to connect any Entity Framework objects directly into a REST service end-point with almost no code.</li>    <li>The 3 service factories are not available in SharePoint 2007, this makes writing services VERY COMPLEX and I don't recommend doing it in 2007.&#160; But you are not out of luck, JavaScript can call the 2007 SOAP services, as long as the correct SOAP envelop is formed before the POST call.&#160; Luckily there are awesome people that has done most of this work: <a title="http://spservices.codeplex.com/" href="http://spservices.codeplex.com/">http://spservices.codeplex.com/</a></li>    <li>IMPORTANT: I did not explain what the jQuery.ajax's cache: false argument is.&#160; This is very important.&#160; When you call a REST service via a URL, if you do not very the URL/Query string, your browser will return you the same data that it has downloaded previously, and give you a cached copy.&#160; This can be really bad since your service isn't actually called.&#160; jQuery gets around this by appending a random number at the end of the query string, like this:     <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint-Saturday-Melbourne-update_14095-?fileId=14760064" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top: 0px; border-right: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://johnliu.net/resource/Windows-Live-Writer-SharePoint-Saturday-Melbourne-update_14095-?fileId=14760065" width="512" height="128" /></a>      <br /> ?_=12312123      <br />      <br />This ensures the query string is unique and browser's cache mechanism won't interfere.&#160; HTTP Response code 200 is success.&#160; Rather than 304 which is browser cache.</li> </ul>]]></description><wfw:commentRss>http://johnliu.net/blog/rss-comments-entry-13414884.xml</wfw:commentRss></item></channel></rss>
