<?xml version="1.0" encoding="UTF-8"?>
<!--Generated by Squarespace Site Server v5.11.81 (http://www.squarespace.com/) on Tue, 29 May 2012 01:42:29 GMT--><feed xmlns="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/"><title>John Liu .NET: Time for Fun in SharePoint</title><subtitle>Blog</subtitle><id>http://johnliu.net/blog/</id><link rel="alternate" type="application/xhtml+xml" href="http://johnliu.net/blog/"/><link rel="self" type="application/atom+xml" href="http://johnliu.net/blog/atom.xml"/><updated>2012-05-25T06:22:25Z</updated><generator uri="http://www.squarespace.com/" version="Squarespace Site Server v5.11.81 (http://www.squarespace.com/)">Squarespace</generator><entry><title>SharePoint in a single page, now with List Item edit</title><category term="SharePoint"/><category term="code"/><id>http://johnliu.net/blog/2012/5/25/sharepoint-in-a-single-page-now-with-list-item-edit.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/5/25/sharepoint-in-a-single-page-now-with-list-item-edit.html"/><author><name>JohnLiu.NET</name></author><published>2012-05-25T06:22:25Z</published><updated>2012-05-25T06:22:25Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>&#160;</p>  <p>Here's the latest screenshot from this project on <a href="http://spaspa.codeplex.com">http://spaspa.codeplex.com</a></p>  <p>&#160;</p>  <p><img src="http://johnliu.net/storage/JL-SPA-7.png" /></p>  <p>&#160;</p>  <p>I've put in buttons that allows you to edit a list item, and that drops the item into edit mode.</p>  <p>Here I'm modifying the Title field.&#160; When you hit Save, it will commit the changes back to SharePoint.</p>  <p>Twitter Bootstrap UI turns out to be really good at guessing screen sizes and adapt.&#160; Here's the page in landscape mode.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-54ce13626b48_E502-?fileId=18403543" 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-54ce13626b48_E502-?fileId=18403545" width="799" height="904" /></a></p>]]></content></entry><entry><title>VS.NET 2008, VSeWSS 1.3 and SafeControl</title><category term="SharePoint"/><id>http://johnliu.net/blog/2012/5/10/vsnet-2008-vsewss-13-and-safecontrol.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/5/10/vsnet-2008-vsewss-13-and-safecontrol.html"/><author><name>JohnLiu.NET</name></author><published>2012-05-10T02:44:44Z</published><updated>2012-05-10T02:44:44Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p><em>Oh VSeWSS how I've NOT missed you.&#160; </em></p>  <p>I was compiling an old solution package for SharePoint 2007, this solution has 6 web parts but the WSP package's manifest only has SafeControl lines for 4 of them.&#160; Somehow, it is discriminating against my newest 2 additions to the family.</p>  <p>In VS.NET 2010, the settings for whether a web part feature should be included in SafeControl is off the WSP Package view.&#160; It automatically adds the current DLL, as well as giving us an option to add more additional assemblies (via the special package solution designer).</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-400b766720a8_AC35-?fileId=18123012" 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-400b766720a8_AC35-?fileId=18123013" width="783" height="157" /></a></p>  <p>&#160;</p>  <p>In VS.NET 2008 and SharePoint 2007, the way it determines whether or not to include a Web Part when it generates the manifest file seems...&#160; almost, <em>bizarre and <strong>magical</strong></em>.</p>  <p>&#160;</p>  <h3>This is how it works</h3>  <ol>   <li>During packaging, VSeWSS reads the DLL to determine if there are web parts within it that needs a SafeControl line.</li>    <li>When it finds them, it modifies a temporary file that it uses during packaging, under project\bin\Debug\solution\manifest.xml</li>    <li>The packaging process than packs up everything under \solution\ into a WSP file, and the manifest file is stored within the WSP file.</li>    <li>What's confusing, is that <strong>VSeWSS is not reading the right DLL </strong>that's compiled from this project, instead, if you have an older copy of the DLL in the GAC, it will actually read the GAC version over your newly built DLL.      <br />      <br />The end result, is that you think you are crazy and you don't understand why it's arbitrarily deciding to add 4 SafeControl lines, but not all 6.</li> </ol>  <p>&#160;</p>  <h3>Fix</h3>  <p>The fix is pretty simple, if you manually deploy the DLL to the GAC first, then repackage again, it'll pick up the additional web parts within the DLL and add them to your SafeControl list.</p>  <p>&#160;</p>  <h3>Why have I never seen this before</h3>  <p>If you are deploying to the local machine for testing, you actually may not even see this error - since when you deploy the currently built solution to the local machine it also puts the new DLL into the GAC.&#160; </p>]]></content></entry><entry><title>SharePoint Single Page Application day 4</title><category term="SharePoint"/><id>http://johnliu.net/blog/2012/5/9/sharepoint-single-page-application-day-4.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/5/9/sharepoint-single-page-application-day-4.html"/><author><name>JohnLiu.NET</name></author><published>2012-05-09T14:43:34Z</published><updated>2012-05-09T14:43:34Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Did a bit of clean up and finally I've got what I can call the first <em>awesome </em>screen shot.</p>  <p>This is a Single Page Application deployed to SharePoint, and talks to SharePoint via the Client Object Model as well as the REST interface.</p>  <p>The page does not Postback.&#160; It always talk to SharePoint via AJAX.</p>  <p><img src="http://johnliu.net/storage/JL-SPA-4.gif" width="640" height="385" /></p>  <h3>&#160;</h3>  <h3>So far:</h3>  <ul>   <li>Package 1 ASPX page in a solution package</li>    <li>Reference jQuery, Knockout</li>    <li>Layout using Twitter's Bootstrap</li>    <li>Grabs lists via Client Object Model</li>    <li>Grabs list items via REST interface</li>    <li>The darn thing is beautiful </li> </ul>  <p>&#160;</p>  <h3>To come next:</h3>  <ul>   <li>CRUD for list items</li>    <li>Document download</li>    <ul>     <li>Document upload?</li>   </ul>    <li>List paging</li>    <li>Use different icons for lists and document libraries on left navigation</li>    <li>A favicon</li>    <li>An actual Title for the page</li>    <li>Site navigation (this will do post back - since we'll be navigating between say <a href="http://server/">http://server/</a> to <a href="http://server/publishing/">http://server/publishing/</a> ).</li>    <li>Quick search / filter</li>    <li>An <em>interesting </em>picture thumb-nail viewer</li> </ul>  <p>&#160;</p>  <p>Check it out on <a href="http://spaspa.codeplex.com/">http://spaspa.codeplex.com/</a> and let me know what you think!</p>]]></content></entry><entry><title>SharePoint 2010 as a Single Page Application (teaser)</title><category term="SharePoint"/><id>http://johnliu.net/blog/2012/5/3/sharepoint-2010-as-a-single-page-application-teaser.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/5/3/sharepoint-2010-as-a-single-page-application-teaser.html"/><author><name>JohnLiu.NET</name></author><published>2012-05-03T17:11:11Z</published><updated>2012-05-03T17:11:11Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>What is a Single Page Application?&#160; Essentially, an application disguised as a single web page.&#160; Like the official &quot;Twitter&quot; web application.&#160; You click, things happen, data is loaded and released asynchronously, layouts are arranged and displayed.&#160; Like magic.</p>  <p>On a crazy <a href="https://twitter.com/#!/johnnliu/status/197923698743836672">Thursday afternoon I had the mad idea</a> of building a Single Page Application on top of SharePoint.</p>  <p>This is a sneak preview of my work so far on this goal:</p>  <p><img src="http://johnliu.net/storage/JL-SPA-1.gif" /></p>  <p>&#160;</p>  <h2>The story so far</h2>  <ul>   <li>Everything in a SharePoint farm solution      <ul>       <li>Deploys to /_layouts/JL-SPA/SPA.aspx - <strong>one single page</strong>! </li>     </ul>   </li>    <li>UI layout using <a href="https://dev.twitter.com/blog/bootstrap-twitter">Twitter Bootstrap</a> - what you see above is based on the <a href="http://twitter.github.com/bootstrap/examples/fluid.html">Fluid example template</a>       <ul>       <li>Twitter Bootstrap is based on <a href="http://lesscss.org/#-client-side-usage">Less.js</a> </li>     </ul>   </li>    <li>UI binding using <a href="http://knockoutjs.com/">Knockout.JS</a>       <ul>       <li>With <a href="http://knockoutjs.com/documentation/plugins-mapping.html">Knockout.Mapping.js</a> addon </li>     </ul>   </li>    <li>Additional glue with <a href="http://jquery.com/">jQuery</a> </li>    <li>Reading from SharePoint via OOTB REST service API      <ul>       <li>The list of libraries from my current site is returned and bound to the list on the left (see above picture).&#160; I call it a mini success in setting up the scaffolding.&#160; Will continue another day. </li>     </ul>   </li>    <li>Exposes _spPageContextInfo object </li>    <li>Expose SP.ClientContext objects/scripts      <ul>       <p><!--EndFragment--></p>     </ul>   </li> </ul>  <p>&#160;</p>  <p>This is the entire project so far:</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint_28D9-?fileId=18009183" 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-SharePoint_28D9-?fileId=18009184" width="253" height="554" /></a></p>  <p>&#160;</p>  <h2>Still to come</h2>  <ul>   <li>UI for lists      <ul>       <li>Sorting for lists. </li>        <li>Determine columns for lists. </li>     </ul>   </li>    <li>UI for viewing items </li>    <li>UI for editing items </li>    <li>?&#160; Add SPServices?&#160; There are some pretty useful workflow use cases in this library. </li> </ul>  <p>&#160;</p>  <h2>Call for help!</h2>  <p>I think I might be out of my mind on this one.&#160; If you want to join in and hack some JavaScript, yell out and help me out!&#160; </p>  <p>Great opportunity to learn some really cool technology and have a lot of fun!</p>]]></content></entry><entry><title>InfoPath - creating a custom FormServer page to embed your own JavaScript goodness</title><category term="InfoPath"/><category term="SharePoint"/><id>http://johnliu.net/blog/2012/4/27/infopath-creating-a-custom-formserver-page-to-embed-your-own.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/4/27/infopath-creating-a-custom-formserver-page-to-embed-your-own.html"/><author><name>JohnLiu.NET</name></author><published>2012-04-27T05:38:49Z</published><updated>2012-04-27T05:38:49Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>&#160;</p>  <p>From time to time, people ask about how to embed JavaScript within InfoPath - there are all kinds of reasons why you'd want to do this, and in this example, I'll focus on a previous use case (<a href="http://johnliu.net/blog/2012/3/27/infopath-disabling-backspace-key-in-browser-form.html">Disabling backspace key in InfoPath browser form</a>) that I've discussed - to disable the backspace key when you don't have a textbox selected - so that the user isn't dumped back to the previous page in Internet Explorer - a terribly woeful user experience.</p>  <h2>Steps</h2>  <ol>   <li>Create a SharePoint solution in VS.NET </li>    <li>Add mapping for Layouts </li>    <li>Copy contents from the OOTB FormServer.aspx file to our custom aspx page </li>    <li>Deploy to see how it works </li>    <li>Add our own, additional JavaScript </li> </ol>  <p>&#160;</p>  <h2>1. Creating a VS.NET SharePoint Project</h2>  <p>&#160;</p>  <p>The key point here is that you will need the CKS extensions for VS.NET 2010.&#160; Grab them first from Extension Manager.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-91518fe02231_BDD3-?fileId=17894086" 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-91518fe02231_BDD3-?fileId=17894087" width="479" height="194" /></a></p>  <p>Because we are going to build an application page that is deployed into SharePoint Root, this project has to be a farm solution.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-91518fe02231_BDD3-?fileId=17894088" 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-91518fe02231_BDD3-?fileId=17894089" width="603" height="343" /></a></p>  <p>&#160;</p>  <h2>2. Map to _layouts in your SharePoint solution</h2>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-91518fe02231_BDD3-?fileId=17894091" 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-91518fe02231_BDD3-?fileId=17894132" width="838" height="507" /></a></p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-91518fe02231_BDD3-?fileId=17894133" 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-91518fe02231_BDD3-?fileId=17894134" width="256" height="180" /></a></p>  <p>&#160;</p>  <h2>3. Add our custom aspx page</h2>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-91518fe02231_BDD3-?fileId=17894135" 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-91518fe02231_BDD3-?fileId=17894137" width="577" height="549" /></a></p>  <p>You may get an security warning from VS.NET to trust CKS - allow this.</p>  <p>The Basic Site Page is the simplest page that can be added to a SharePoint solution.&#160; It is essentially one ASPX page without any code behind.&#160; In this example this page is sufficient for our needs.</p>  <p>&#160;</p>  <p>At this point, we should go visit our own SharePoint root and see how the default FormServer.aspx page is built.</p>  <p>Navigate to: C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\TEMPLATE\LAYOUTS\</p>  <p>And look for FormServer.aspx</p>  <p>You'll see that the page is actually really simple - all the hard work is in the XmlFormView control.&#160; The page passes query parameters to the XmlFormView control.</p>  <p>Copy all the content of this out of the box FormServer.aspx file</p>  <p>Return to our project, and paste all the contents over the sample JLFormServer.aspx file.&#160; Now, your JLFormServer.aspx file should be exactly the same as the out of the box FormServer.aspx file.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-91518fe02231_BDD3-?fileId=17894138" 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-91518fe02231_BDD3-?fileId=17894139" width="852" height="577" /></a></p>  <p>&#160;</p>  <h2>4. Deploy to see how it works</h2>  <p>Package and deploy the solution to SharePoint - you'll see this deployed to SharePoint root.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-91518fe02231_BDD3-?fileId=17894140" 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-91518fe02231_BDD3-?fileId=17894142" width="419" height="310" /></a></p>  <p>&#160;</p>  <p>Take a normal form server url:</p>  <p><a title="http://spg-dev-jl/_layouts/FormServer.aspx?XsnLocation=http://spg-dev-jl/CopyForms/Forms/template.xsn&amp;SaveLocation=http%3A%2F%2Fspg%2Ddev%2Djl%2FCopyForms&amp;Source=http%3A%2F%2Fspg%2Ddev%2Djl%2FCopyForms%2FForms%2FAllItems%2Easpx&amp;DefaultItemOpen=1" href="http://spg-dev-jl/_layouts/FormServer.aspx?XsnLocation=~site/Forms/Forms/template.xsn&amp;DefaultItemOpen=1">http://spg-dev-jl/_layouts/FormServer.aspx?XsnLocation=~site/Forms/Forms/template.xsn&amp;DefaultItemOpen=1</a></p>  <p>Change it to our custom aspx page:</p>  <p><a href="http://spg-dev-jl/_layouts/JLFormServer/JLFormServer.aspx?XsnLocation=~site/Forms/Forms/template.xsn&amp;DefaultItemOpen=1">http://spg-dev-jl/_layouts/<font style="background-color: #ffff00">JLFormServer/JLFormServer.aspx</font>?XsnLocation=~site/Forms/Forms/template.xsn&amp;DefaultItemOpen=1</a> </p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-91518fe02231_BDD3-?fileId=17894143" 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-91518fe02231_BDD3-?fileId=17894144" width="700" height="344" /></a></p>  <p>&#160;</p>  <p>Hey works fine :-)</p>  <p>&#160;</p>  <h2>5. Adding our own JavaScript goodness</h2>  <p>Go back to our JSFormServer.aspx page, and look for the &lt;head&gt; element.&#160; Let's add some JavaScript.</p>  <p>&lt;script src=&quot;<a href="http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js&quot;">http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.7.2.min.js&quot;</a>&gt;&lt;/script&gt;     <br />&lt;script&gt;     <br />&#160;&#160;&#160; function document_keydown(e) {     <br /></p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (e.keyCode == 8){  <br />  <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var t = e.target;  <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (t) {  <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (t.tagName == &quot;INPUT&quot;) return; // ignore textbox  <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (t.tagName == &quot;TEXTAREA&quot;) return; // ignore multi-line textbox  <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }  <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; if ($(t).hasClass(&quot;ms-inputuserfield&quot;)) {  <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return; // ignore people picker, by checking for ms-inputuserfield css class  <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; }  <br />  <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // letting us know we've ate a backspace key&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; alert('Ate a backspace key, hew!', false);</p>  <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; // cancel backspace navigation    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; e.preventDefault();     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; e.stopImmediatePropagation();     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; return false;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }     <br />&#160;&#160;&#160; };</p>  <p>&#160;&#160;&#160; $(document).keydown(document_keydown);    <br />&lt;/script&gt;</p>  <p>Package everything and deploy to server.</p>  <p>&#160;</p>  <h2>Result: everything in action!</h2>  <p>&#160;</p>  <p>Navigate to our custom form server page again.</p>  <p><a href="http://spg-dev-jl/_layouts/JLFormServer/JLFormServer.aspx?XsnLocation=~site/Forms/Forms/template.xsn&amp;DefaultItemOpen=1">http://spg-dev-jl/_layouts/JLFormServer/JLFormServer.aspx?XsnLocation=~site/Forms/Forms/template.xsn&amp;DefaultItemOpen=1</a> </p>  <p>Select a textbox and delete a few characters - this should work fine, as the JavaScript function allows this.</p>  <p>Un-focus from a textbox, so that the focus is now on the main page - and press backspace.&#160; Normally, this would trigger Internet Explorer to go back to the previous page in history, but now this event is caught by our JavaScript and cancelled!</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-91518fe02231_BDD3-?fileId=17894145" 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-91518fe02231_BDD3-?fileId=17894146" width="399" height="410" /></a></p>  <p>&#160;</p>  <h2>Note</h2>  <p>Finally, comment out the alert in your JavaScript - I'm sure you don't want to drive your users crazy.</p>  <p>// letting us know we've ate a backspace key    <br />// alert('Ate a backspace key, hew!');</p>  <p>&#160;</p>  <h2>Summary</h2>  <ul>   <li>We looked at how to build and deploy a simple site page to SharePoint root </li>    <li>What a FormServer.aspx page looks like </li>    <li>How we can add additional JavaScript to our Custom FormServer.aspx page </li> </ul>  <h2>&#160;</h2>  <h2>Update</h2>  <ul>   <li>Updated the javascript function that includes my latest tweaks for multiline textbox and people picker</li> </ul>]]></content></entry><entry><title>InfoPath 2010 - query using the REST interface</title><category term="InfoPath"/><category term="SharePoint"/><id>http://johnliu.net/blog/2012/4/26/infopath-2010-query-using-the-rest-interface.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/4/26/infopath-2010-query-using-the-rest-interface.html"/><author><name>JohnLiu.NET</name></author><published>2012-04-26T16:05:45Z</published><updated>2012-04-26T16:05:45Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>&#160;</p>  <p>This is an exercise to play with the REST interface, which works extremely well with InfoPath 2010.</p>  <h2>Scenario</h2>  <ol>   <li>We have a postcode list.&#160; Filled with post codes and suburbs.</li>    <li>In InfoPath, we want to select a post code and populate the corresponding data from the list.</li>    <li>While this is possible using the old owssvr.dll trick, Let's do this one with the REST interface - which is a much cleaner example.</li> </ol>  <p>&#160;</p>  <h2>Steps</h2>  <ol>   <li>Here's a very simple custom list, &quot;Postcodes&quot;     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881157" 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-2010---using-the-REST-interface_16D0-?fileId=17881181" width="672" height="199" /></a>      <br /></li>    <li>The REST interface to select a row, using a filter:     <br /><a href="http://spg-dev-jl/_vti_bin/listdata.svc/Postcodes?$filter=Code eq '2000'">http://spg-dev-jl/_vti_bin/listdata.svc/Postcodes?$filter=Code eq '2000'</a>      <br /></li>    <li>This returns the following XML - you can see Title and Code in the XML      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881208" 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-2010---using-the-REST-interface_16D0-?fileId=17881211" width="696" height="640" /></a>      <br /></li>    <li>Create an InfoPath 2010 form, create a few fields:&#160; &quot;Postcode&quot; (number) and &quot;Suburb&quot; (text, shown as expression)     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881225" 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-2010---using-the-REST-interface_16D0-?fileId=17881241" width="197" height="123" /></a>      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881244" 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-2010---using-the-REST-interface_16D0-?fileId=17881245" width="646" height="241" /></a>      <br /></li>    <li>Create a secondary data source and connect to the earlier REST service.     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881267" 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-2010---using-the-REST-interface_16D0-?fileId=17881275" width="478" height="313" /></a>      <br /></li>    <li>Add an action to Postcode - on change, set the REST URL, then execute the query.     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881301" 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-2010---using-the-REST-interface_16D0-?fileId=17881304" width="218" height="168" /></a>      <br />The Change REST URL action appears when you have REST secondary data sources in your 2010 form.      <br />      <br />We want to change the URL based on a formula, so set it to:      <br />concat(&quot;http://spg-dev-jl/_vti_bin/listdata.svc/Postcodes?$filter=Code%20eq%20'&quot;, . ,&quot;'&quot;)      <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881307" 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-2010---using-the-REST-interface_16D0-?fileId=17881336" width="494" height="305" /></a>      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881339" 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-2010---using-the-REST-interface_16D0-?fileId=17881341" width="227" height="498" /></a>      <br /></li>    <li>Finally, copy the new suburb back into our Suburb field from the updated secondary data source.     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881342" 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-2010---using-the-REST-interface_16D0-?fileId=17881343" width="494" height="305" /></a>      <br />      <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881347" 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-2010---using-the-REST-interface_16D0-?fileId=17881349" width="320" height="367" /></a>      <br />      <br /></li>    <li>The completed rule(s)     <br /><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881351" 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-2010---using-the-REST-interface_16D0-?fileId=17881352" width="234" height="496" /></a></li> </ol>  <p>&#160;</p>  <h2>Result</h2>  <p>Running in InfoPath rich client</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881354" 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-2010---using-the-REST-interface_16D0-?fileId=17881356" width="226" height="245" /></a></p>  <p>Running in Form Server</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath-2010---using-the-REST-interface_16D0-?fileId=17881359" 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-2010---using-the-REST-interface_16D0-?fileId=17881366" width="517" height="446" /></a></p>  <p>&#160;</p>  <h2>Summary</h2>  <ul>   <li>The REST data source is actually a FileQueryConnection and expects an XML result.&#160; In InfoPath 2010 though, we have the new action to &quot;change&quot; the path using rules which is really the unsung hero of this story.</li>    <li>And thus we got to play with REST and InfoPath 2010</li> </ul>  <p>&#160;</p>  <h2>Download</h2>  <p><a title="http://johnliu.net/storage/RestPostcodesForm.xsn" href="http://johnliu.net/storage/RestPostcodesForm.xsn">http://johnliu.net/storage/RestPostcodesForm.xsn</a></p>]]></content></entry><entry><title>SharePoint - stripping HTML tags in XSL</title><category term="SharePoint"/><id>http://johnliu.net/blog/2012/4/26/sharepoint-stripping-html-tags-in-xsl.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/4/26/sharepoint-stripping-html-tags-in-xsl.html"/><author><name>JohnLiu.NET</name></author><published>2012-04-26T08:29:03Z</published><updated>2012-04-26T08:29:03Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Sometimes, when working with XSL (for example, in a content query webpart), you would like to limit the number of characters returned in a field in the template.&#160; </p>  <h2>Trimming field length in XSL</h2>  <p>The itemstyle template may look something like this:</p>  <p>&#160;&#160;&#160; &lt;xsl:template name=&quot;FAQ&quot; match=&quot;Row[@Style='FAQ']&quot; mode=&quot;itemstyle&quot;&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:variable name=&quot;SafeLinkUrl&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:call-template name=&quot;OuterTemplate.GetSafeLink&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:with-param name=&quot;UrlColumnName&quot; select=&quot;'LinkUrl'&quot;/&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:call-template&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:variable&gt;    <br />    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;dt&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;a href=&quot;{$SafeLinkUrl}&quot; class=&quot;title&quot; onclick=&quot;GoToLink(this);return false;&quot; target=&quot;_self&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:value-of select=&quot;@Title&quot; /&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/a&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/dt&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;dd&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:choose&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:when test=&quot;string-length(@Answer) &amp;gt; 150&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:value-of select=&quot;<font style="background-color: #ffff00">concat(substring(@Answer,0,150),'...')</font>&quot; disable-output-escaping=&quot;yes&quot;/&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:when&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:otherwise&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:value-of select=&quot;@Answer&quot; disable-output-escaping=&quot;yes&quot;/&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:otherwise&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:choose&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160; &lt;/dd&gt;     <br />&#160;&#160;&#160; &lt;/xsl:template&gt;    <br /></p>  <p>The interesting part is where the @Answer field is rendered - if the length of this field is beyond 150 characters, it will return the first 150 characters and append an ellipsis (...)</p>  <h2>Problem when we have a HTML field</h2>  <p>The technique is pretty simple, but it is not fool proof - when the field you are trying to trim is an HTML / Rich field, you have a big problem - the trimming may suddenly cut off valid HTML, to return an invalid HTML.</p>  <p>Imagine, if the @Answer field was:</p>  <p>&lt;div&gt;   <br />&#160;&#160;&#160;&#160; &lt;span&gt;a great answer&lt;/span&gt;    <br />&lt;/div&gt;</p>  <p>And we perform:</p>  <p>substring(@Answer, 25)</p>  <p>Then we'll get:</p> <strong><font style="background-color: #ffff00">&lt;div&gt;     <br />&#160;&#160;&#160;&#160; &lt;span&gt;a great answe</font></strong>r&lt;/span&gt;  <br />&lt;/div&gt;  <p>&#160;</p>  <p>You are now returning really bad HTML to the browser:</p>  <p>&lt;dd&gt;   <br />&#160;&#160;&#160; <font style="background-color: #ffff00">&lt;div&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;span&gt;a great answe</font>...    <br />&lt;/dd&gt;</p>  <p>See how the HTML isn't terminated correctly with the proper end-tags.&#160; If you are lucky, the browser guesses correctly and doesn't break your page.&#160; Many times though, it's all down hill from here.</p>  <p>&#160;</p>  <h2>Using XSL to strip HTML tags from your field.</h2>  <p align="left">A very simple solution is to add an additional XSL template to strip out the HTML tags from your field before rendering it.&#160; A simple version can be found on <a href="http://dotnetslackers.com/Community/blogs/kaushalparik/archive/2008/08/30/strip-out-html-tags-to-display-plain-text-in-xslt.aspx">this article</a>.</p>  <p>&#160;</p>  <h3>1.&#160; Add this removeHtmlTags template in your XSL</h3>  <p>&lt;xsl:template name=&quot;removeHtmlTags&quot;&gt;   <br />&#160;&#160;&#160; &lt;xsl:param name=&quot;html&quot;/&gt;    <br />&#160;&#160;&#160; &lt;xsl:choose&gt;    <br />&#160;&#160;&#160;&#160;&#160; &lt;xsl:when test=&quot;contains($html, '&amp;lt;')&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:value-of select=&quot;substring-before($html, '&amp;lt;')&quot;/&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;!-- Recurse through HTML --&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:call-template name=&quot;removeHtmlTags&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:with-param name=&quot;html&quot; select=&quot;substring-after($html, '&amp;gt;')&quot;/&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:call-template&gt;    <br />&#160;&#160;&#160;&#160;&#160; &lt;/xsl:when&gt;    <br />&#160;&#160;&#160;&#160;&#160; &lt;xsl:otherwise&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:value-of select=&quot;$html&quot;/&gt;    <br />&#160;&#160;&#160;&#160;&#160; &lt;/xsl:otherwise&gt;    <br />&#160;&#160;&#160; &lt;/xsl:choose&gt;    <br />&#160; &lt;/xsl:template&gt;</p>  <p>&#160;</p>  <h3>2. Modify your ItemStyle to use the removeHtmlTags template in an XSL variable</h3>  <p>&#160;&#160;&#160; &lt;xsl:template name=&quot;FAQ&quot; match=&quot;Row[@Style='FAQ']&quot; mode=&quot;itemstyle&quot;&gt;&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:variable name=&quot;SafeLinkUrl&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:call-template name=&quot;OuterTemplate.GetSafeLink&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:with-param name=&quot;UrlColumnName&quot; select=&quot;'LinkUrl'&quot;/&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:call-template&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:variable&gt;    <br /><font style="background-color: #ffff00">&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:variable name=&quot;textAnswer&quot;&gt;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:call-template name=&quot;removeHtmlTags&quot;&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:with-param name=&quot;html&quot; select=&quot;@Answer&quot; /&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:call-template&gt;      <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:variable&gt;</font><font style="background-color: #ffff00">     <br /></font>&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;dt&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;a href=&quot;{$SafeLinkUrl}&quot; class=&quot;title&quot; onclick=&quot;GoToLink(this);return false;&quot; target=&quot;_self&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:value-of select=&quot;@Title&quot; /&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/a&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/dt&gt;    <br />    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;dd&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:choose&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:when test=&quot;string-length(<font style="background-color: #ffff00">$textAnswer</font>) &amp;gt; 150&quot;&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:value-of select=&quot;concat(substring(<font style="background-color: #ffff00">$textAnswer</font>,0,150),'...')&quot; disable-output-escaping=&quot;yes&quot;/&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:when&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:otherwise&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;xsl:value-of select=&quot;<font style="background-color: #ffff00">$textAnswer</font>&quot; disable-output-escaping=&quot;yes&quot;/&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:otherwise&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; &lt;/xsl:choose&gt;    <br />&#160;&#160;&#160;&#160;&#160;&#160; &lt;/dd&gt;     <br />&#160;&#160;&#160; &lt;/xsl:template&gt;    <br /></p>  <h2>Summary</h2>  <ol>   <li>Use substring to strip fields to a certain number of characters - so you don't return everything</li>    <li>For HTML fields, add removeHtmlTags template and use call-template to get the result into an XSL variable first</li> </ol>]]></content></entry><entry><title>SPSPerth 2012 Update</title><category term="Public Announcement"/><category term="SharePoint"/><category term="code"/><id>http://johnliu.net/blog/2012/4/20/spsperth-2012-update.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/4/20/spsperth-2012-update.html"/><author><name>JohnLiu.NET</name></author><published>2012-04-20T15:30:17Z</published><updated>2012-04-20T15:30:17Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>This is my first time in Perth!&#160; Hello Perthites!</p>  <p>I even took a train to Cottesloe beach - a very nice beach, I watched the sunset and did what any geek would do, I checked in the <strong>Indian Ocean</strong>.</p>  <p>I will update this post with links after the sessions. In the mean time, you can reference my current collection of articles on these topics regarding REST, custom service, and Knockout</p>  <p><a href="http://johnliu.net/rest/">http://johnliu.net/rest/</a></p>  <h2>Downloads</h2>  <ul>   <li>Custom REST service      <ul>       <li><a title="http://johnliu.net/storage/SharePoint%20REST%20and%20jQuery5.pptx" href="http://johnliu.net/storage/SharePoint%20REST%20and%20jQuery5.pptx">http://johnliu.net/storage/SharePoint%20REST%20and%20jQuery5.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>   </li>    <li>Knockout and SharePoint      <ul>       <li><a title="http://johnliu.net/storage/Creating%20Knockout%20User%20Experiences%20in%20SharePoint%20with%20JavaScript_spsper201204.pptx" href="http://johnliu.net/storage/Creating%20Knockout%20User%20Experiences%20in%20SharePoint%20with%20JavaScript_spsper201204.pptx">http://johnliu.net/storage/Creating%20Knockout%20User%20Experiences%20in%20SharePoint%20with%20JavaScript_spsper201204.pptx</a> </li>        <li><a title="http://johnliu.net/storage/knockout-rest-sspug-201202.zip" href="http://johnliu.net/storage/knockout-rest-sspug-201202.zip">http://johnliu.net/storage/knockout-rest-sspug-201202.zip</a> </li>     </ul>   </li> </ul>  <h2>Reference</h2>  <p>Make sure you follow Matt Menezes   <br /><a href="http://spmatt.wordpress.com/">http://spmatt.wordpress.com/</a> </p>  <p>He's a regular at Perth user group circles and knows a lot about Knockout.&#160; I think he is slotted in for a future session in the upcoming months - don't miss it!</p>]]></content></entry><entry><title>SharePoint - Recursive delete SPWeb PowerShell script</title><category term="SharePoint"/><id>http://johnliu.net/blog/2012/4/11/sharepoint-recursive-delete-spweb-powershell-script.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/4/11/sharepoint-recursive-delete-spweb-powershell-script.html"/><author><name>JohnLiu.NET</name></author><published>2012-04-11T06:44:11Z</published><updated>2012-04-11T06:44:11Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>Or, what happens when you stuffed up and need to clean up a lot of sites created by accident.</p>  <p>&#160;</p>  <h2>Story</h2>  <ul>   <li>I have a feature receiver stapled to my site template, it checks a few conditions, does a few things, then creates 1 subsite and stops</li>    <li>The new subsite is created, and runs the same receiver, it checks a few more conditions, does a few things.&#160; It <em>shouldn't </em>create any subsites.</li>    <li>This afternoon, it did.&#160; The process <em>did not</em> stop.</li>    <li>Ouch</li> </ul>  <p>&#160;</p>  <h2>Problem</h2>  <ul>   <li>You can't delete the higher level web object when it has subsites.&#160; You can't follow the subsites because the path has gone way deep.</li>    <li>Sounds like time for a good PowerShell script</li> </ul>  <p>&#160;</p>  <h2>Script</h2>  <p>$web = get-spweb http://dev/ourprojects/nsw/1000</p>  <p>function CleanSite( $w )   <br />{    <br />&#160;&#160;&#160; $ws = $w.Webs;    <br />&#160;&#160;&#160; foreach( $w1 in $ws)     <br />&#160;&#160;&#160; {    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; CleanSite($w1)    <br />&#160;&#160;&#160; }    <br />&#160;&#160;&#160; echo $w.Title    <br />&#160;&#160;&#160; $w.Delete()</p>  <p>}</p>  <p>CleanSite $web</p>  <p>&#160;</p>  <h2>Closing thoughts</h2>  <p>My initial fears were that the feature receivers has gone berserk and I'd have hundreds of subsites to clean up.&#160; This turned out to be not the case - I only had about 12 subsites.&#160; I'm wondering if there was a SharePoint error that prevented deeper subsites from being created.&#160; So the disaster really wasn't that bad.&#160; 12 subsites I can manage.&#160; </p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-SharePoint--_E7CC-?fileId=17608662" 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--_E7CC-?fileId=17608663" width="216" height="189" /></a></p>]]></content></entry><entry><title>SharePoint Saturday 2012 public announcements</title><id>http://johnliu.net/blog/2012/4/4/sharepoint-saturday-2012-public-announcements.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/4/4/sharepoint-saturday-2012-public-announcements.html"/><author><name>JohnLiu.NET</name></author><published>2012-04-03T19:57:41Z</published><updated>2012-04-03T19:57:41Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>&nbsp;</p>
<p>A new year means more SharePoint Saturdays!</p>
<p>In Australia, first up, is <a href="http://sharepointsaturday.org/perth/">SPS Perth</a>.&nbsp; This will be held on April 21st.&nbsp; In just 3 weeks' time.&nbsp;</p>
<p>This will also be the first time I head over to Western Australia to mingle with the locals.&nbsp; Hope to do a bit of exploring, and make lots of new friends and followers.</p>
<p><img src="http://sharepointsaturday.org/perth/SiteImages/2012_SPS_Logo_300.jpg" alt="" /></p>
<p>Perth 21/04   <br />Brisbane 02/06 <a href="http://spsbne12-eorg.eventbrite.com/">http://spsbne12-eorg.eventbrite.com/</a><br />Adelaide 30/06 (?)<br />Melbourne 04/08 (?)<br />Canberra 22/09 (?)<br />Sydney 27/10 (?)</p>]]></content></entry><entry><title>InfoPath, custom WCF Service, Word and Open XML SDK (outline)</title><category term="InfoPath"/><category term="SharePoint"/><id>http://johnliu.net/blog/2012/4/3/infopath-custom-wcf-service-word-and-open-xml-sdk-outline.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/4/3/infopath-custom-wcf-service-word-and-open-xml-sdk-outline.html"/><author><name>JohnLiu.NET</name></author><published>2012-04-03T03:57:11Z</published><updated>2012-04-03T03:57:11Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>This upcoming series of articles promise to be far more exciting than the title.</p>  <h2>Scenario</h2>  <p>How do you use an InfoPath form document to populate a word document with content controls.&#160; </p>  <p>&#160;</p>  <h2>Steps:</h2>  <ol>   <li>Building a Word document template with Content Control place holders</li>    <li>Use Content Control toolkit to bind values to place holders in the template to an embedded custom XML <em>(hey, isn't an InfoPath document an XML file?)</em></li>    <li>Creating a WCF service to take a Word template document, and replace the custom XML, by the power of Open XML SDK<em> (2.0, of course)</em>.</li>    <li>Invoking the WCF service from within an InfoPath document to generate a word template version of itself!</li>    <li>Finally, a bit of discussion on where Word Automation services fits in the bigger picture, as well as thoughts on best practices.</li> </ol>  <p>   <br />Drop a comment below if you have any specific questions relating to these steps.&#160; Specifically, if you can think of a far better title for this series.</p>  <p>Otherwise, stay tuned!&#160; :-)</p>]]></content></entry><entry><title>InfoPath - disabling backspace key in browser form</title><category term="InfoPath"/><category term="SharePoint"/><category term="code"/><id>http://johnliu.net/blog/2012/3/27/infopath-disabling-backspace-key-in-browser-form.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/3/27/infopath-disabling-backspace-key-in-browser-form.html"/><author><name>JohnLiu.NET</name></author><published>2012-03-27T03:48:13Z</published><updated>2012-03-27T03:48:13Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>How to disable the backspace key using Javascript/jQuery for an InfoPath browser form in SharePoint 2010.</p>  <p>&#160;</p>  <h2>The problem</h2>  <p>One really troubling problem with almost all web solutions is how the Backspace key works.&#160; By default, it tells your browser to go back to the previous page in history.</p>  <p>If you are just browsing around on your Intranet, this is probably not a big deal - firstly, you wouldn't be pressing backspace unless you actually wanted to go back.&#160; Secondly, if you did indeed made a mistake and pressed the backspace key, you'd just undo that action by clicking the forward button, or navigate to another link.&#160; No problem.</p>  <p>&#160;</p>  <p>When you are filling in a form on the browser though, such as through InfoPath, suddenly the backspace key is a big deal.&#160; You users may be using the backspace key to delete text that they are in the middle of entering.&#160; And if they didn't have a textbox focused, the backspace key is sent to the browser form, and suddenly you have a problem.&#160; The form disappeared, and you have lost information.</p>  <p>&#160;</p>  <p>InfoPath is quite smart - it remembers which view you are supposed to be on, and when you navigate to an outdated browser historical view of the form - Form Server will automatically redirect you forward to show you the correct form you are supposed to be viewing.&#160; This is good, at least in the navigation sense.&#160; So the only remaining problem is the lost data - your user may have had a whole page filled out and this mistake has just cleared their form.&#160; Not good.</p>  <p>&#160;</p>  <h2>Enter Javascript</h2>  <p>So, the plan is simple:</p>  <ol>   <li>Inject javascript to the existing browser form </li>    <li>Listen to keydown event for a backspace key (keycode 8) </li>    <li>Eat the event and stop it from propagation, so the browser don't see it </li> </ol>  <p>Using jQuery, you'll need this simple function.</p>  <p>&#160;</p>  <p>function document_keydown(e) {    <br />&#160;&#160;&#160; if (e.keyCode == 8 &amp;&amp; e.target.tagName != &quot;INPUT&quot;) { </p>  <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; // letting us know we've ate a backspace key    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; SP.UI.Notify.addNotification('Ate a backspace key, hew!', false);</p>  <p>&#160;&#160;&#160;&#160;&#160;&#160;&#160; // cancel backspace navigation    <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; e.preventDefault();     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; e.stopImmediatePropagation();     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; return false;     <br />&#160;&#160;&#160; }     <br />};</p>  <p>$(document).keydown(document_keydown);</p>  <p>&#160;</p>  <h2>Injecting Javascript in modal dialog</h2>  <p>&#160;</p>  <p>If you are using SharePoint 2010's modal dialog to show InfoPath in a modal popup, it's slightly trickier.</p>  <p>&#160;</p>  <p>// grab a reference to the modal window object in SharePoint    <br />var w = SP.UI.ModalDialog.showModalDialog(options);</p>  <p>if (w) {    <br />&#160;&#160;&#160; // get the modal window's iFrame element     <br />&#160;&#160;&#160; var f = w.get_frameElement();</p>  <p>&#160;&#160;&#160; // watch frame's readyState change - when page load is complete, re-attach keydown event    <br />&#160;&#160;&#160; // on the new document&#160;&#160;&#160;&#160;&#160;&#160;&#160; <br />&#160;&#160;&#160; f.onreadystatechange = function(e) {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; if (f.readyState == 'complete') {     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; var fwin = f.contentWindow || f.contentDocument;     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160; $(fwin.document).keydown(document_keydown);     <br />&#160;&#160;&#160;&#160;&#160;&#160;&#160; }     <br />&#160;&#160;&#160; };     <br />}     <br /></p>  <h2>Result</h2>  <p>&#160;</p>  <p>nom-nom-nom backspace keys.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-InfoPath---disabling-the-backspace-key_C9A8-?fileId=17336136" 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---disabling-the-backspace-key_C9A8-?fileId=17336138" width="459" height="153" /></a></p>  <p>&#160;</p>  <p>Note, because the Javascript catches the keypress event at the document level.&#160; If your user still has focus on the input (textbox) level, the event will not be stopped - so your user still will be able to backspace when they are using a textbox.</p>]]></content></entry><entry><title>Re: Sorry dad, you'll understand, someday</title><category term="Public Announcement"/><category term="rant"/><id>http://johnliu.net/blog/2012/3/23/re-someday-dad-youd-understand.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/3/23/re-someday-dad-youd-understand.html"/><author><name>JohnLiu.NET</name></author><published>2012-03-23T03:55:21Z</published><updated>2012-03-23T03:55:21Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>This is a quick blog post, in response to Zac Gorman's excellent Magical Game Time comic.</p>  <p><a href="http://magicalgametime.com/post/19718347285/ill-stop-when-ive-saved-the-world-and-fallen-in">http://magicalgametime.com/post/19718347285/ill-stop-when-ive-saved-the-world-and-fallen-in</a></p>  <p>As you play through the game <a href="http://en.wikipedia.org/wiki/EarthBound">Earthbound</a> as the kid protagonist Ness, your phone would ring every few hours, and your dad would ask you if you'd like to take a break.&#160; If you say Yes, it'd save the game and switch it off.</p>  <p>The comic cleverly replies as Ness: I'll stop when I've saved the world and fallen in love.&#160; (Sorry dad, you'll understand someday).</p>  <p>&#160;</p>  <p>My boy is still three, he doesn't understand about saving the world, or falling in love, <em>yet</em>.&#160; I'm sure he will soon.&#160; And here'd be my response to him:</p>  <ul>   <li>All dads were boys once.      <br />We already understood. </li>    <li>So off you go, save the world.      <br />Go and fall in love with your girl. </li>    <li>You do what you have to do.      <br />This is your time, we don't expect you to hold back, or stay at home. </li>    <li>When you are tired from saving the world, stop by and have some hot chocolate and ice cream.      <br />We will always be your biggest fan. </li> </ul>  <p>&#160;</p>  <p>We will return to our regular SharePoint updates soon.&#160; </p>]]></content></entry><entry><title>AUSPC 2012 summary</title><category term="SharePoint"/><category term="code"/><id>http://johnliu.net/blog/2012/3/21/auspc-2012-summary.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/3/21/auspc-2012-summary.html"/><author><name>JohnLiu.NET</name></author><published>2012-03-21T06:13:18Z</published><updated>2012-03-21T06:13:18Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>I had an awesome time presenting Building your own custom REST Services and consuming them with jQuery AJAX in the Australian SharePoint Conference 2012.&#160; A big thank you to the developers that came and geeked out with me for an hour on a Wednesday afternoon.</p>  <h2>Notes</h2>  <p>When you build a custom WCF Service using the CKS template, it is deployed to a subfolder the web front end's ISAPI folder, which, in turn, is mapped to the site's /_vti_bin/ folder.</p>  <p><a href="http://johnliu.net/resource/Windows-Live-Writer-e99d07cdc232_EF34-?fileId=17235393" rel="lightbox"><img style="background-image: none; border-bottom: 0px; border-left: 0px; margin: 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-e99d07cdc232_EF34-?fileId=17235394" width="244" height="144" /></a></p>  <p>&#160;</p>  <p>It appears that in my earlier attempt to create an incomplete version of the <a href="http://johnliu.net/blog/2012/1/16/sharepoint-here-is-a-rest-service-project-item-template.html">REST service template item</a>, I interfered with how CKS's templates worked - and correct features for deploying the WCF service is no longer being included in the package.&#160; While existing items were updated and deployed, the new WCF service that I was creating wasn't being deployed to the ISAPI folder.</p>  <p>I've removed the REST template item from my Visual Studio .NET environment, and voila - the WCF services deployed nicely once again.</p>  <p>So that's one mystery resolved.&#160; Now I scratch my head about how to fix my VS.NET REST template item.</p>  <p>&#160;</p>  <h2>Downloads</h2>  <ul>   <li><a title="http://johnliu.net/storage/SPGSvcWp.zip" href="http://johnliu.net/storage/SPGSvcWp.zip">http://johnliu.net/storage/SPGSvcWp.zip</a></li>    <li><a title="http://johnliu.net/storage/SharePoint%20REST%20and%20jQuery4.pptx" href="http://johnliu.net/storage/SharePoint%20REST%20and%20jQuery4.pptx">http://johnliu.net/storage/SharePoint%20REST%20and%20jQuery4.pptx</a></li> </ul>]]></content></entry><entry><title>AUSPC 2012 quick update</title><category term="Public Announcement"/><category term="SharePoint"/><category term="rant"/><id>http://johnliu.net/blog/2012/3/20/auspc-2012-quick-update.html</id><link rel="alternate" type="text/html" href="http://johnliu.net/blog/2012/3/20/auspc-2012-quick-update.html"/><author><name>JohnLiu.NET</name></author><published>2012-03-20T11:48:25Z</published><updated>2012-03-20T11:48:25Z</updated><content type="html" xml:lang="en-US"><![CDATA[<p>I'm in the strange and calm interlude between day 1 and day 2 of awesomeness in the annual Australian SharePoint Conference (AUSPC) 2012.</p>  <p>Day 1 has been a lot of fun.&#160; Manned the user group booth in the morning with <a href="http://www.danielbrown.id.au/default.aspx">Dan Brown</a>.&#160; Met many of the SharePoint guys in the community that I haven't seen for the last 6 month to a year.&#160; Talked to a number of vendors, and attended a number of awesome sessions on the developer track.</p>  <p>I also got to sit on the panel answering developer questions amongst the legends like <a href="http://nickhadlee.wordpress.com/">Nick Hadlee</a>, <a href="http://www.sharepoint-tips.com/">Ishai Sagi</a>, <a href="http://blog.brianfarnhill.com/">Brian Farnhill</a> and <a href="http://wss.made4the.net/default.aspx">Jeremy Thake</a></p>  <p>The oddest part is probably with MCA SharePoint <a href="http://channel9.msdn.com/Events/Speakers/Wayne-Ewington">Wayne Ewington</a> sitting in the audience.&#160; Every time we said something silly he'd start shaking his head and we'd all stop.&#160; Hilarious.</p>  <p>&#160;</p>  <p>Tomorrow morning, my session on <a href="http://mobile.sharepointconference.com.au/agenda/details/578">Building your own custom REST Service and consuming them with jQuery AJAX</a> is running in the developer track at 10:30am.&#160; Hope to see everyone there.</p>  <p>All my related resources and presentations on this topic are summarized on <a href="http://johnliu.net/rest">http://johnliu.net/rest</a></p>]]></content></entry></feed>
