In a recent project, I was creating a contracts management portal within SharePoint. As part of the contracts request process, the sales team were able to link info path documents that represented each of the service lines that formed the contract. Each of these service line documents (InfoPath forms) formed the basic service outline and contained within them both the Standard functions of the service as well as Optional (chargeable) functions that could be added on.
The business process required the Sales team to add these optional functions in at a later point in the process and in order to make the process easier, I wanted to display the optional functions on the same page that the Sales team would be adding the request in the notes field as an aide memoir. I figured the best way to do this would be to use jQuery and AJAX to get a copy of the InfoPath XML to parse. I certainly wasn’t wrong as this approach has worked very well indeed.
To get this to work, on my dashboard page I have a Data View Web Part that shows me the contract request that I’m working with. It outputs various bits of information, but the key piece that I was interested in for this was the selected Service Line Documents. These were from a standard multiple select lookup field, and rendered on the page as links in the form
This wasn’t ideal and I really wanted to display them as an unordered list. Looping through a collection in XSLT generally means recursive templates, so I decided that as I was using jQuery heavily for this, I’d use that to do the styling and inject the function calls that I needed. All I did do, was add an ID to the service line links table cell so that I could find it easily with jQuery.
<td width="75%" class="ms-vb" id="serviceLineLinks"> <xsl:value-of select="@Service_x0020_Lines" disable-output-escaping="yes" /> </td>
On the right hand web part zone, I added a content editor web part, and linked it to an html file in the Site Assets library. This enabled me to use SharePoint designer to do the html editing. I’ve added the following jQuery JavaScript to format the links as I want them, and to add a click here bit of text with the relevant click event handler.
$(document).ready(function() { var serviceLineLinks = $('#serviceLineLinks > a'); serviceLineLinks.wrapAll('<ul/>').each(function() { var thisLink = $(this); var linkedDoc = thisLink.text(); var str = linkedDoc.substr(0,linkedDoc.lastIndexOf('.')); thisLink.text(str); thisLink.wrap('<li/>'); var wrappingLI = thisLink.parent(); wrappingLI.height('18px'); wrappingLI.append('<span> (Click here to show optional services)</span>').click(function(){processXML(linkedDoc)});; }); });
I’ve not been using jQuery in earnest for long, but I have to say it does make writing JavaScript a lot more fun!! (If you can see a more efficient way of doing what I’ve done in jQuery, please add a comment as i’d love to improve my use of jQuery!).
I think that’s pretty straight forward what I’m attempting, but to summarize..
- Get all the links in our table cell
- Wrap them all in a UL element
- Then For each link in the collection
- Extract the text value of the link
- Remove the .xml for display
- Replace the text value
- Wrap the element in an LI tag.
- Make the LI element 18px high.
- Add a new span to the LI with a click handler attached calling my processXML function with the document name.
This gives us the following output on the page
The next step is to handle the opening and display of the infopath document. As my CEWP webpart is already on the page in the right hand web zone, I decided to use that to hold the additional information as I could control the target dom elements easier that way.
In the top of the CEWP, I added two empty DIV elements.
<div id="ServiceLineOutputHeading"></div> <div id="ServiceLineOutput"></div>
And then added the following JavaScript functions to handle the call from the click links.
function processXML(docName) { $.ajax({ type: "GET", url: "https://sharepoint2010dev/contracts/servicelinedescriptions/" + docName + "?NoRedirect=true", datatype: "xml", cache: false, contentType: "text/xml; charset=\"utf-8\"", complete: processResult }); }
This is a fairly straight forward ajax request, I had to do a fair amount of playing around with the URL used by SharePoint before I narrowed it down to calling for the file directly but with the NoRedirect=true flag. This stops SharePoint trying to show the infopath file in the browser for the current request (which would be silly for us as we just want the XML!). Once complete, we process the result with the following code.
function processResult(xData,status) { //extract our required XML using the responseText object var extractedXML = xData.responseText; //Find the header node var serviceLineName = $(extractedXML).find('[nodename=my:ServiceLineName],ServiceLineName'); //Find the collection of nodes from within our document var optServiceFeatures = $(extractedXML).find('[nodename=my:OptionalServiceFeature],OptionalServiceFeature'); //Setup our new header content and inject it into the empty DOM element var headingBlockContent = "<h2>"; headingBlockContent = headingBlockContent + serviceLineName.text(); +"</h2>"; var headingBlock = document.getElementById('ServiceLineOutputHeading'); headingBlock.innerHTML = headingBlockContent; //Now set up our unordered list and process the node collection for each option item var newContentBlock = "<ul>"; $(optServiceFeatures).each(function(index) { newContentBlock = newContentBlock + "<li id='optService" + index + "'>" + $(this).text() + "</li>"; }); var newContentBlock = newContentBlock + "</ul>"; var testOutput = document.getElementById('ServiceLineOutput'); testOutput.innerHTML = newContentBlock; }
When clicking on the link next to the chosen service line, our additional info pops up alongside for easy reference. Clicking on other service lines just updates the same div with the new info as you’d expect.
Using AJAX to get at the contents of InfoPath has proved very useful here, and I can see my self using it again soon.
Paul.
1 ping
[…] Using SharePoint hosted infopath documents as contents in a SharePoint page. […]