04 January 2013

codeless: double eval

/TECH
My current job title is SharePoint Developer. However, my work is a lot more specific than that. Yes I develop for SharePoint, but more specifically I develop custom, codeless web forms using InfoPath as my primary design tool. The key here is that everything I do doesn't contain custom code but rather out-of-the-box functionality used creatively. And boy do I get creative. Over the next several blog entries I want to explore some of the codeless designs I've found, developed, and refined.

The first trick I want to talk about is one that I use a ton: the double eval. When I first started developing with InfoPath I found that there were several things I couldn't do that I could in C++. Now, I understand that InfoPath isn't a programming language, but it is based on web-technology and several web languages support. So why the hell can't I systematically grab data from a repeating field?! Well, you can. I remember looking at all the functions I could use in an expression once and when I got to eval(), I had no idea how to use it. Even the description of for using it was cryptic: "Returns a node-set containing the result of the expression for each set of elements in the context field." If you added it to the expression, you got the following template:
eval(double click to insert field, "type expression here")
Now I don't know about you but I learn much more about a function by seeing an example of it being used. I finally saw an example one day of the following expression from Infopath codeless programming (walkthrough) 2:
eval(eval(Person, 'concat(my:AccountId, "|")'), "..")
At first I couldn't figure out what was going on, but after I used it several times in different forms I figured out how the two eval() functions were working together. Let's break this down starting with the inner eval().
eval(Person, 'concat(my:AccountId, "|")')
This eval() is referencing the field Person and then using concat() on it. The trick here is that the concat() function is being run relative to where Person is located. This means that if you need to do a comparison to another field with your concat(), you need to write the xpath as if the concat was running on Person. Say you want to filter AccountId based on Department. If you were to look at the xpath for the two fields you might get something like this:
- MyFields
  - Person
    = AccountId
  = Department
You'll notice that Person and Department are parallel and AccountId is a child of Person. For our concat() above to filter AccountId using Department, it would have to be done like so:
'concat(my:AccountId[../../my:Department = "IT"], "|")'
What this does is back up twice relative to where AccountId is located and then looks for Department. It's really important to know where in the hierarchy an expression is going to run. You may have also noticed that the entire expression for the eval() is enclosed in single quotes, not double quotes. That's because the expression needs to use double quotes to function correctly, thus you change the overall encapsulation to single quotes.
eval(eval(Person, 'concat(my:AccountId, "|")'), "..")
The outer eval is easier to break down and is where the "looping" action actually occurs. The outer eval() is treating the inner eval() as the field it is working on and the ".." as the expression. The unique thing about the expression here is that it is looking for one thing: when the field has to go back or up a level in the hierarchy. As soon as that happens, the outer eval returns the results of the inner eval() that occurred on each instance of Person, in this case, a string of concatenations that results in the output of a single string of text. The output would look something like this:
jcool|cbrown|ppatty|lucyvanpelt|
This is now a really useful way to gather info into a single field for further use and/or processing. I've used it to concatenate the usernames from a SharePoint list to use in a comparison in the form for security, creating a list of approvals still needed, and even doing a sort of "group by" query on a repeating table.

Thanks to Alec Pojidaev and posting that little trick to his blog. It's come in extremely useful. Check out his blog for some other codeless solutions. Click here to return to my listing of "codeless" blog entries.

Until next time:
Work hard. Play harder.

No comments:

Post a Comment