Friday, August 31, 2012

InfoPath 2010 - embed HTML for rich and web forms


Do we like the SharePoint content editor web part?  Yes!
What if there's a way to add your own HTML in your InfoPath form, and have it appear for both web forms and rich (InfoPath Filler) forms?

Here are the quick steps:

  1. Create an external XML file to store the HTML we need
  2. Add the external XML file as a secondary data source for the InfoPath form
  3. Use the Rich Text control and bind the result from the secondary data source
  4. Using resources in the form (images, CSS)
    1. Tricks for InfoPath Filler Rich Form
    2. Tricks for InfoPath Browser Form
  5. Adding your own CSS
  6. Notes
    1. Script tag doesn't work (stripped from rich text control).
    2. Steps to refresh HTML content of the XML resource

1. Create the XML file

This is documented in MSDN Inserting line breaks into text using Rules 

This is pretty much the same thing - I'm inserting a namespace here so InfoPath knows this is a HTML block of text.
<?xml version="1.0" encoding="utf-8"?>
<html>
  <myhtml>
    <b xmlns="http://www.w3.org/1999/xhtml" >A Bold Hello</b> World
  </myhtml>
</html>
Save it as html.xml

2. Add the XML file as a secondary data source

image
Figure: Add a secondary XML document
image

3. Use the Rich Text control and bind the result from the secondary data source


Remember to change the Rich Text Box to Read-Only
image
Figure: Add a new rich text box, then change it's binding
image
Figure: Bind it to the secondary data source

Run it in Preview (InfoPath Filler)
image
Figure: InfoPath Filler - looks good
Publish and run in browser (Browser Form):
image
Figure: InfoPath Form Server - also looks good

4. Use Image from form resources


Let's go one step further and play with resources such as images.  Add an image into the form's resource files
image
Figure: Go to resource files
image
Figure: Add a picture "Save.png"

Modify the HTML to refer to this image. 
<?xml version="1.0" encoding="utf-8"?>
<html>
  <myhtml>
    <b xmlns="http://www.w3.org/1999/xhtml">A Bold Hello</b> World
   <img xmlns="http://www.w3.org/1999/xhtml" src="Save.png" border="1" />
  </myhtml>
</html>
Preview this:
image
Figure: works great in InfoPath Filler

Publish and view in Form Server:
image
Figure: Doesn't work so well in Browser Form

image
Figure: Raw HTML

4.1 Using form resources in Form Server

Let's see how does the Form Server handle images.

image
Figure: Create a picture button

image
Figure: Set the Picture to the resource

Publish, then check HTML source in the browser for the new picture:
<img style="width: 100%; height: 50px; position: static;" alt="" src=http://server/_layouts/FormResource.aspx?solutionId=XXX&solutionFile=Save.png hoverSrc=""/>
So the format is:
/_layouts/FormResource.aspx?solutionId=xxx&solutionFile=Save.png

Update this back in our HTML file.
<?xml version="1.0" encoding="utf-8"?>
<html>
  <myhtml>
    <b xmlns="http://www.w3.org/1999/xhtml">A Bold Hello</b> World
    <img xmlns="http://www.w3.org/1999/xhtml" src="Save.png" border="1" />
    <img xmlns="http://www.w3.org/1999/xhtml" src="/_layouts/FormResource.aspx?solutionId=XXX&amp;solutionFile=Save.png" />
  </myhtml>
</html>
IMPORTANT: Remember to escape the & in the query parameter to &amp;
Publish to Form Server again:
Compare the same form published on two different clients:
image

5. Add your own CSS

Let's try some other tags, this is the STYLE tag:
<?xml version="1.0" encoding="utf-8"?>
<html>
  <myhtml>
    <style xmlns="http://www.w3.org/1999/xhtml" >
       img {
           border: dotted 2px purple !important;
       }
    </style>
    <b xmlns="http://www.w3.org/1999/xhtml">A Bold Hello</b> World
    <img xmlns="http://www.w3.org/1999/xhtml" src="Save.png" />
    <img xmlns="http://www.w3.org/1999/xhtml" src="/_layouts/FormResource.aspx?solutionId=XXX&amp;solutionFile=Save.png" />
  </myhtml>
</html>
image

Purple dotted borders.  Notice how it is also affecting the Ribbon in the Browser Form.
Use this to your advantage ;-)  

6. Notes

  1. Firstly, <SCRIPT> won't work.  The rich text control strips them out.
  2. Refreshing the XML file when you update it is a bit of a painful process.  This is just the way it is with secondary data sources in SharePoint.  If you are using offline files, you need to go through the wizard again to overwrite the previous connection (and refresh your offline cache).  But if you are storing that XML file in SharePoint - you can just publish a new version there and tell InfoPath not to cache it.

InfoPath - removing newline (CRLF) using rules


  1. In InfoPath (and in Windows in general), a newline is two characters \r\n (carriage return, followed by a newline character).
  2. You can't easily use \r or \n within InfoPath rules, since the XML is escaped into \\r and \\n defeating your intention.
  3. First, add a characters secondary data source: Add an external XML file for characters
    You should get this secondary data source with the special characters we need.
    image 
  4. On the field that you want to remove newlines, add a changed rule:
    image

    The translate rule is:
    translate(., @crlf, "")
    or expanded xpath:
    translate(., xdXDocument:GetDOM("characters")/lookups/characters/@crlf, "")

    use select field and change the datasource to characters. 
  5. To prevent this rule from running into infinite loop, set a condition:

    image

    The expression is:
    contains(., xdXDocument:GetDOM("characters")/lookups/characters/@crlf) 
  6. Result:
    image  

Test it!


image
Test typing something with newline

image
Rule runs and removes any new line characters

InfoPath - an example of using an XML file for special characters


This is an old trick relating to inserting special characters (such as carriage returns) and tricking InfoPath to stop removing them! 
I've decided to take some screenshots to show what you should be expecting when you apply this technique.

The XML file

image

The Data Connection

image
image

A formula to use it

image
The advanced Xpath is:
concat("my", xdXDocument:GetDOM("characters")/lookups/characters/@crlf, "hello", xdXDocument:GetDOM("characters")/lookups/characters/@crlf, "world")

Result - Rich Client

image

Result - Web Browser Form

image

The HTML generated in the browser form is:
<TEXTAREA ...>my
hello
world</TEXTAREA>

Notice it has the correct carriage returns creating the new lines.

The example XSN file if you want to download it and have some fun

BPA and Error Handling in InfoPath 2010 Forms


BPA and Error Handling in InfoPath 2010 Forms
Business Process Automation (BPA) with SharePoint and InfoPath includes subtle caveats such as “Error Handling” when warning users of application errors when a field needs to be populated.   Microsoft has placed some defaults within the application that are a bit obscure and sometimes inconsistent with the actual error that is occurring.  In this very brief post, I wanted to give you the idea of creating a new warning by using rules in an InfoPath 2010 form without using the default Microsoft message error message. 
Scenario:  Typically, when a form is created  in InfoPath, many of the fields may be mandatory or required to be populated.  The problem occurs when the message provided is not complete or informative enough for the users to understand what steps need to be taken.  The typical message resembles the following:
Fig 1.0
 Error1

Some of my associates in the SharePoint realm have used and set policies for organizations using rules to make messages more consistent for all SharePoint developers. Instead of providing error messages like the above, create rules that will display messages that are relevant to the given field of error. In the following example both the “Title” and the “Company” are mandatory fields.
Fig 2.0
 InfoPath1

If these fields are not populated then the user will receive error messages like the following:
Fig 3.0
 Error2

By Adding rules to the submit button the default error message in InfoPath 2010 can be avoided.
Example of Rules that were applied:
Fig 4.0
 Rules1
By limiting your user group's exposure to erronious error messages, there will be less user frustration, and they will be more likely to embrace the benefits of your solution. 

InfoPath - Get the current user without writing code


  1. With InfoPath opened go to Tools > Data Connections, and click 'add...' to add a new data connection to the form. This opens up the Data Connection Wizard.
  2. We want to receive data from the WS about the current user, so choose receive data' and click next.
  3. Our data source is a WS so choose 'Web Service' and next.
  4. Now you will have to point the wizard to the WS. Type an address similar to thishttp://ServerName/_vti_bin/UserProfileService.asmx  and click next.
  5. Here you get a list of all methods for that WS, choose GetUserProfileByName and click next.
  6. In this screen you can specify what parameters are sent to the method, we are relying on the method's ability to return the current user name if no value is passed to it, so we will leave this as is (no value is passed to the method) and click next.
  7. Click next and make sure 'Automatically retrieve data when form is opened' is checked.
  8. Finish the wizard.
The GetProfileByName method returns a PropertyData array. You can think of it as a repeating table of name and value pairs.
So Now that you have a data connection that can get the current users, you can use it values. In this example I will show the user's first name in a textbox.
  1. Add a textbox to the form.
  2. Go to the first textbox's properties (double click it).
  3. In the 'Default Value' part, click the 'fx' button next to the 'Value' field. this opens up the formula builder dialog.

    vc 
  4. Click 'Insert field or group'.

     
  5. In the data sources drop down, choose the GetUserProfileByName data source.
  6. Expand all groups under the 'dataFields' group, and choose the 'value' field. Don't click OK yet!

     
  7. With data 'value' field selected, click the 'Filter Data...' button and 'Add...'.
  8. In the first drop down (value) select 'Select a field or group...' and choose the 'Name' field under the 'PropertyData' group.



     
  9. Leave the middle drop down as is ('is equal to') and in the last drop downchoose 'type a text...'.

  10. This is the part where you specify which property to put in the textbox. As we said the method returns multiple properties about the user. For this textbox we want to put the user's first name in, so type 'FirstName' (this is case sensitive!). I have included the property list you can use here (just below), so if you want some other property, just type its name instead.
  11. That's it, all we have to do is to confirm everything so Click 'OK' for every open dialog box until you are back in the design mode.
  12. click 'Preview' and see the wonder!
  13. If you want more details repeat steps 1-11 and enter different property names in step 10.
Finally, as I Promised, here is the complete list of default profile properties get returned by the userprofileservice. I think they are pretty self explained:
UserProfile_GUID
AccountName
FirstName
LastName
PreferredName
WorkPhone
Office
Department
Title
Manager
AboutMe
PersonalSpace
PictureURL
UserName
QuickLinks
WebSite
PublicSiteRedirect
SPS-Dotted-line
SPS-Peers
SPS-Responsibility
SPS-Skills
SPS-PastProjects
SPS-Interests
SPS-School
SPS-SipAddress
SPS-Birthday
SPS-MySiteUpgrade
SPS-DontSuggestList
SPS-ProxyAddresses
SPS-HireDate
SPS-LastColleagueAdded
SPS-OWAUrl
SPS-ResourceAccountName
SPS-MasterAccountName
Assistant
WorkEmail
CellPhone
Fax
HomePhone

Thursday, August 9, 2012

There has been an error while loading the form. A required resource could not be downloaded. To try to resume the download, refresh the page.

There has been an error while loading the form. A required resource could not be downloaded. To try to resume the download, refresh the page.



Please dont use http://192.168.1.114/
use with domain name http://globas/