The blogger's eternal struggle for blog reader comments

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.

 

A simple wish, in my simple world

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.

Increasingly though, and I'll be very honest, I think I do this for the warm fuzzy feeling when people leave a nice comment.

I really like comments.  I like to know what people think of what I wrote.  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.  I want to know if they think my writing style needs work.  May be I need a spellchecker.

I crave for that feedback.  I'm over the moon when I get it.

I'm bothered when I see lots of traffic, but no comments.  Am I doing something wrong, am I not helping people, do people think I just blubber about rubbish.  People are searching for answers to their problems, did they not find it here?

 

And that's just the beginning of my problems...

Enter the giant social networks

And their walled gardens.

The best thing about the social networks is that it encourages people to be chatty, and comment on things.  The worse thing about it is that it's all hidden behind walled gardens and I can't see them.

I love talking to my friends on Facebook and Twitter.  But sorry, conversations in those walled gardens doesn't return to the original content creator.  Actually, what's happening is that people are gossips behind my back!  Preposterous!

 

I really gave it some thought...

A good idea starts with me taking a small step

I realized what I can do, and this is more a behaviour change than something technical.  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.

If I think the content can be improved, I will suggest it.  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.

Love the blogging and long live the bloggers!

SharePoint - disguise your long running AJAX calls

I have to confess I haven't had so much laugh in SharePoint for a long time.

OK, here's the problem:

  1. 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. 
  2. Basically, it takes a while to run.  May be around 15 seconds.

 

image
Figure: Once you click this link it gets busy on the server.

image
Figure: Once it's clicked, I disable the link

Put up a dialog to tell the user to wait

The first thing we should do is put up a dialog to tell the user hey something's happening.

Waldek Mastykarz has an awesome article on how to do most of this, so I won't type out his code.  http://blog.mastykarz.nl/sharepoint-2010-ui-tip-non-obtrusive-progress-messages/

image 
Figure: Here's my blocking dialog.  No close box.  It spins for about 15 seconds and then disappears when the AJAX call receives a success response.

 

But waiting for 15 seconds really gets boring.

You realize that you must use better messages, and update it as you wait. 

image

image

image

 

Here's the javascript code.

 

    var msgs = [
        "Calculating web paths",
        "Negotiating with site collection",
        "Creating empty site template",
        "Activating Features",
        "Synchronizing template",
        "Setting up form libraries",
        "Copying pages",
        "Configuring webparts",
        "Chasing chickens"];   
   
    var p = function(){
        if (waitDialog) {
            var msg = msgs[Math.floor(Math.random()*msgs.length)];
            waitDialog.get_html().getElementsByTagName('TD')[1].innerHTML = msg;
            setTimeout(p, 1000);
        }
    };
    setTimeout(p,1000);

Create an array of status messages - these (aside from the chicken) are really what the REST service is doing.  I also create a function p, which choses a random message and updates the waitDialog.  Repeat every second.  When the AJAX call completes, it destroys the waitDialog, and set it to null.  This stops the setTimeout loop.

 

Some sort of magic happened

Suddenly, because things are updating on screen, the process doesn't seem long at all.  You click it, a few messages flash past, before you know it the site's created and ready to go.

So there you have it, the trick really is just a clever disguise. 

You show users random messages and distract them from the fact that they have to wait for 15 seconds.

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 - Concat SharePoint list with the Eval function (aka Voodoo)

 

It really can't hurt to play with the crazy XPath capabilities within InfoPath.  This is documented in many places, starting:

http://blogs.msdn.com/b/infopath/archive/2006/04/05/569338.aspx

Which offered possibly the best explanation of how this technique with Eval() actually works.  I prefer to remembered this as PURE VOODOO.

 

1. Create our SharePoint list

image

 

2. Create a secondary data connection to the list

image

image

 

3. Drag the dataFields section into the form, to create a common binding parent

image

This step makes step 4 a lot easier, since the Eval loop is relative and works on the repeating section inside the dataFields section.

 

4. Add expression box within this Section

image

The Expression is:
xdMath:Eval(xdMath:Eval(d:SharePointListItem_RW, 'concat(d:Title, ":")'), "..")

 

5. Result:

image

InfoPath - managing lots of tooltip in your browser form

This is an idea that I've been brooding for a long time.  Finally got a prototype implemented.

 

We have a complicated looking InfoPath form.  We've always wanted to have lots of help (i) tooltips.  The picture below alone has 24 information tips.

image

 

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.

image

This approach works OK, but is very tedious.  Each one of our views are massive, and we have about 10 of them.  Some fields re-appear on different views and need to have the same tooltip.  This is also not very manageable - we can't modify the tooltip easily without republishing the InfoPath form.

 

An idea begin brewing by combining an external XML file along with the Rich HTML control, something that I've experimented recently.

/blog/2011/5/30/infopath-2010-embed-html-for-rich-and-web-forms.html
/blog/2011/10/12/infopath-an-example-of-using-an-xml-file-for-special-charact.html

 

Idea!

  1. Produce an XML file that has all our tooltips.
  2. Store this file in SharePoint
  3. In InfoPath, connect to this XML file as an external datasource, always load it from server
  4. Bind the XML fields to Rich HTML controls

 

1. My tooltip XML file. 

My XML file, with 2 entries in it for "office" and "state". 

Note the content of the two entries is essentially a HTML IMG tag.  With the source pointing to an image stored in SharePoint, and a tooltip.

<?xml version="1.0" encoding="utf-8"?>
<html>
  <office>
   <img xmlns="http://www.w3.org/1999/xhtml" src="/Style Library/Images/info.png" border="0" title="Select the Office that will administer this project" />
  </office>
  <state>
    <img xmlns="http://www.w3.org/1999/xhtml" src="/Style Library/Images/info.png" border="0" title="Select the State that this project will report to" />
  </state>
</html>

 

2. Store this file in SharePoint

I store this in SharePoint, on /Style Library/html-tooltip.xml.

image

 

3. Add secondary data source in InfoPath

Add XML datasource.

image

Select "Access the data from specified location"

image

Always retrieve data

image

Result data connection

image

 

4. Bind to Rich HTML controls

Switch to the secondary data source in the Fields tool pane.
Drag my new entry for "State" with the right click contextual menu.
Select Rich Text Box

image

 

There's quite a bit of clean up to do:
image

  • Remove the label
  • Set the background shade to No Fill
  • 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.
  • Set the height and width to 25px (size of my images).
  • Select Read-Only in the ribbon
    image
  • The result:
    image

 

Extra Note

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.  Sorry, this behaviour is so weird, I do have an ugly workaround but I won't publish it - really ugly.

image

 

See it in action:

image

 

And if you need to change the text, open up the XML file in SharePoint designer, change it, and save the XML file again.

image

image

 

Summary

  • A technique to use one XML file in SharePoint to specify many HTML tooltip elements to be used within an InfoPath form
  • This allows tooltips to be updated independently of templates, and multiple elements in the InfoPath form can share and reuse the same tooltip