Welcome


Welcome, do not let the title fool you. There are no means or resources to teach you how to hack SharePoint. What you will find here are tips and tricks for real life applications. I have many scripts that I have hacked, from other writers, to fit project requirements. I am hopeful I can share them with you so you can utilize the same information.

Requests
if you have a Request, please post them here.

Follow this format if you want to post readable code in comments

[sourcecode language="javascript"]
//your code
[/sourcecode]

Are you experiencing trouble with your children? Are they strong-willed or out-of-control? Remember most kids are not bad, they just make bad choices. Learn how to motivate and influence better choices. Visit theparenthelpcenter.com/.

Changed parents will see changed kids

InfoPath, getting the SharePoint Item ID


Recently, durning an InfoPath (IP) form build, I was tasked to create a method that could capture the SharePoint Item ID. This had to be done on initial form load, because it is possible the user would need to reference this value before form completion. After much research I did find several methods that looked promising. But after much trial and error they all failed, or maybe it was me.

The first one I tried came from this post: http://www.bizsupportonline.net/browserforms/autonumber-infopath-form-submitted-sharepoint-library.htm. I have much respect for S.Y.M. Many of his post have helped me greatly. This solution is destin to cause an issue. Although it will grab the next ID, there is no garauntee that it would not be shared by more than one form and I needed the ID assigned to that form on submit. The I came across another respected blogger in the community Clayton Cobb. He was responding to this very request and referenced one of his recent posts here: http://social.msdn.microsoft.com/Forums/en-US/sharepointinfopath/thread/689e681f-d46a-4621-a0cf-55fd49a0432a.

A combination of both posts was dead on. My problem, I did not read the post in its entirety and for half a day I was
chasing my tail. Reading the post quickly I saw how they were getting the ID and I figure I could return the ID with a filter where IP(fileName) = SP(Name), but Name is not a field that can be selected in the filter, so I went with Title. This is where I failed. eventually I found out that Title field was blank, but not after much frustration. When I finally identified this issue I republished the form and promoted the IP(fileName) and now the filter could compare this to the SP(fileName). this was a simple, but costly error.

After much trial and error I was final able to build a working solution. The concept is on form load, the form checks a field “filename” if blank set the value to a current DateTime.

concat(substring(now(), 6, 2), "-", substring(now(), 9, 2), "-", substring(now(), 1, 4), " T ", substring(now(), 12, 2), "_", substring(now(), 15, 2), "_", substring(now(), 18, 2))

this formula is SharePoint safe and can still be read as DateTime. Once this value is updated or filename field changes, The form is submitted, saved using the filename. At this point there has been no user interaction. with some additional logic and a few rules I am able to retrieve the form ID from the SharePoint library.

In order to retrieve the ID I needed to promote my filename field. The reason as discussed earlier was the Name field is not a field IP can use, and Title is not getting any data that can be used. By promoting the filename field, You now have a field you can compare to grab the ID. In addition to the fielname field I also added formID field. Once these fields are promoted you need to add this library as a secondary data source. When setting up the data souce add filename as one of the selected fields. This will make that data available to query.

During the same action of fielname change a few steps are needed, here are the actions:

  • Submit using data connection (Submit to Library)
  • Query using data connection (Library Name)
  • Set a field’s value: formID = ID[filename (from list) = filename (from form)]

on the last action the formula is not clean. IP converts the first fielname to a guid. not a big deal, but it is hard to read.

So there you have it. You have learned how to automatically generate a filename for a form on load, save the form, and query the library to grab the form’s ID.

InfoPath addDays


On this project I have been on for much time now, feels like forever, I have begun to carve impressive progress. One of the requirements we needed a quick start and end date. The form contained a form start and end date, and a repeating section where each item had a start and end date. For the most part many entries will be back dated to the first of the month and some stamped for the end of the month. I know with script many things are possible, but I really did not want to add more lines of code for something I believe could be handled with a simple rule.

The first thing I was considering was how to implement this. I did not want it taking away from the form, but I needed it to function. I considered using a button control. I removed the fill color and removed the borders. Once I did this it looked like regular text on the form. Now I can format the text and place it anywhere it was needed.

Setting the value to the first day of the month was really simple. You can use today() with concat and substring, replacing the “Day” with “01″

concat(substring(xdDate:Today(), 1, 4), "-", substring(xdDate:Today(), 6, 2), "-01")

If you notice the first substring, it is actually pulling in the year. When I tried this in the format on the field “mm/dd/yyyy” I received a validation error. Microsoft needs the input in this format “yyyy-mm-dd”, although once the value is written to the date field, it is immediately converted back to the field’s format of “mm/dd/yyyy”. Knowing this will make solving the last day of the month a bit easier, so I thought.

Know that getting the first day of the current month is fairly easy, I figured we could get the first day of the next month and subtract 1 day. This would ensure always getting the last day of the current month. I learned this trick when dealing with Calculated Columns and Date fields in SharePoint. Getting the first day of next month was a little trickier than expected, but eventually figured it out. The initial problem was the date length. The standard date length is 10 characters. When I added 1 to current month if it was a single digit, it returned a single digit. I needed a way to add a leading zero. Good thing I had a need for this same requirement on another project, so was easy to figure out how to add a leading zero and 1 month.

 (concat(substring("00", 1, 2 - string-length(substring(xdDate:Today(), 6, 2) + 1))

The first substring tells us the number of digits and how to format it and the nested substring is grabbing the month value, then adding 1 at the end. This brings us very close, but we are still not quite there. Initially I thought I would be able to subtract 1 from the date and I would be done, but this wasn’t the case. So I did a little research and came across a post of similar request and that used the addDays() function and added a negative 1, perfect. This nailed it on the head.

Now putting it all together here is the last day of the current month:

xdDate:AddDays(concat(substring(xdDate:Today(), 1, 4), "-", (concat(substring("00", 1, 2 - string-length(substring(xdDate:Today(), 6, 2) + 1)), (substring(xdDate:Today(), 6, 2)) + 1)), "-01"), -1)

I understand that IP has a calendar picker and this is just as easy to open the calendar to make your selection, but my form could have many items added and using the calendar takes a minimum of 2 clicks. Adding these rules it now takes 1 click. Enjoy!

InfoPath, Microsoft Strikes Back!


It’s been a while since I have posted. It has been very hectic. I am slap dab in the middle of a project and it is kicking my butt. For simplicity purposes I am developing an InfoPath (IP) form for what could be used as a billing system. Although IP could not do this alone it is much easy to develop the UI in IP then to try and replicate its functionality in .NET.

Initially I started out with one single form, but the deeper into the rabbit hole I went the less IP was compliant. My Secondary Data Sources were simple SharePoint (SP) lists. The Sr. Developer dropped some code into SP so any data entered on a list in that site would automagically be updated in a SQL Database. The reason for this was to speed up the data feeds to the IP form. By storing supporting list and the IP form as an XML blob in the db we could write Stored Procedures and pass parameters, thus allowing data filtration before it gets to the form.

Now on the eighth iteration of this form and I’m still struggling a bit with what IP will allow me to do and what needs a bigger hammer to make it work. Several releases prior I went to IP template parts (TP). I chose this path now because I have learned more about the project. Eventually I will roll out many forms which will be variations of the main one. I will be setting them up as templates with prepopulated data. The total number of needed forms is unknown at this time, but I am expecting about 32. Playing with the TPs I figured make one change, and update all, right? Wrong. Well for the most part this is fairly true. Here are some issues I ran into.

When you change or create a TP it has to be added to IP as a control. As an updated TP you have an option to update form with the new TP. This means every form has to be opened to make the update. Most of the time this will be fairly simple except under these conditions

  1. Adding a new field to the TP
  2. Resource files
  3. Button Control IDs
  4. Default values, Rules across TPs (If multiple TP exist on one form)

Let’s start with adding a new field. I did not figure this out right away. It took several modifications to understand when this issue occurred. I found after updating a form with a modified TP the UI of the form looked unchanged (except for the modifications), but when you looked at the schema (field structure) it added a replication of the original node and in addition prefixed all field, group and section nodes in the TP with a “_1″, “_2″ etc…. In the figure you will see to nodes, myLineItems and myLineItems_1.

Maybe this is not critical sometimes, but for this project we are depending on the XPATH for every field. If this changes the code on the back end will break. I struggled a bit with this trying to figure out why this happened only sometimes. So I started noting every step each time I updated the TP and began comparing differences. I found when I added a new field to the TP upon update in the form it would create a new replicated section. Now that I found the culprit I needed to find a solution to prevent this. For now it is nothing fancy. I found If I deleted the part and the field nodes from the form, saved the form and closed it, upon reopen I could add the updated TP and keep my original names for all the fields, groups and sections. I’m not sure why Microsoft would build functionality like this. If I copy a file in windows I get an alert to over write or rename. Why not build this into the TPs, giving the user the choice to over write or create with new name?

Moving on to the Resource Files and how Microsoft strikes again. In the attempt to save time when updating TPs I started adding Resource files to the TPs. This way when updated I would not have to re-add or attach them. For XML files it is not such a big deal, but images used in Picture Buttons is a nightmare. Microsoft decided to replicate these also. So a form with several TPs and several Picture Buttons could end up with 15-20 resource files once the TPs are imported into a form. I do have to give them some credit for the data connections. At least these do not replicate, but are renamed with the TP name at the end. No matter how many times it is updated it will keep that name even when you rename it in the main form. So why can’t we have a similar functionality throughout the form? Now each iteration I roll out I find myself going into the resource files and deleting the duplicates, then updating all the picture buttons and renaming the Control ID’s.

So if I create a button, picture or not, in a TP and add it to a form with a specific name, why on updated does Microsoft give it a default Control ID in the main form? If you are running code off the button click event, once it is renamed the function doesn’t fire. Now I have to go back and touch every button and rename the ID to match the form code. I know what you’re thinking; why not name it in the TP before updating. Yes, I already did this and it does not retain this name. Another major fail!

My final complaint is focused on the maintenance of default values and rules across TPs. I created a multiple select for day of the week using a repeating table. Without going into any major details I set 7 default values one for each day of the week and in the header a checkbox to select/unselect all. By default you can see the first default value. A typo on my part added “Sat” first instead of “Sun”. No matter how many time I have changed this, updated, in the TP or deleted the TP from the form it will not update in my final product. I am forced to go into the main form and make this change there. Again for the most part the rules stay intact, but when Microsoft forces me to delete the existence of the TP because it wants to rename it I lose all the rules I have had setup. Not knowing this can be frustrating when published an administrator approved template, launching the form and nothing works.

This process of elimination took many hours or pulling my hair out. Although some of this stuff may sound obvious when you’re in the fox hole we can sometimes over complicate what we are doing, putting more into it than what we really need to. I am hopeful Microsoft can fix some of these issues on the next release of IP, but I am sure that version will have its issues for us to find and deal with.

InfoPath 2010 Rules Management and the People Picker


I have been getting some real time on InfoPath 2010 and currently in the process of developing a code less form. Eventually code will be added for the back end functionality, but for now I will push InfoPath to its limits. I have two issues I am trying to work through. First one is the userName() function not returning a value equal to currentuser. This most likely is related to the Active Directly account, or how it was set up. One of the new features of IP 2010 is the Contact Selector already part of the arsenal. Several things I have found seem to be related to how users are setup in Active Directory (AD). After several hours of play I was able to get a working solution. Once I had a solution I tried to make it a template part so I could make it available to everyone without configuration, which was a major fail. For some reason Microsoft felt the need to limit this functionality.

Setting this up is fairly easy once you know what has to be done. This is done through the Picker field’s task pane, “Show Advanced view” for field details.

  1. Right click on AccountId
  2. Select Properties
  3. Under default value, select the function builder
  4. Type userName() in the Insert Formula window
  5. Click OK
  6. Confirm “Refresh value when formula is recalculated” is unchecked. Doing this will ensure that this rule will only run once and not every time the form is opened.
  7. Click OK
  8. This must be repeated for the DisplayName for optimum experience

Results: The People picker will result to the person who opens the form and saves it for the first time.

Feel free to contact me with aby questions

Chunking Content – Part 6


In Part 5 we reviewed the Map and how the Block plays a role in its structure. This post will review the units of information Blocks and Maps making it easier to apply Design Principles. This part will conclude the Design Phase of writing.

Block
Blocks are relevant chuncks of content with a label.

Map
Maps are a collection of Blocks with a title.

Components
Block

  • One main idea
  • A Label
  • A Separator

Map

  • No more than seven plus or minus two (7 ± 2) related Blocks
  • A title that reflects the purpose or main idea/content

Summary

In the first Five parts we explained the importance of how we write. The different between on-line writing as compared to paper or books. Outling the the changes to support a layout out the the end user finds easy to use and navigate through. The strucure of Maps and Blocks also provided scanability for the users, which allowed for them to quickly find what was needed.

As we move into the Develop Phase we will also describe the principles used and presentation. You will be able to identify the difference between Process and Procedure. Although Process and Procedure have a similar look and feel because they both deal with action the difference will be determine by the Scope and Detail of the information.

Display options from Choice Multiple Select in separate columns


I recently came across a request to display the options from a choice multiple select across multiple columns Like this:.
results

When I began to work on this I had a totally differnt path. My initial thoughts were to create a calculated field, and then place the values into another calc field with an HTML table. I have used tables before in a calculated field with the help od a script from pathtosharepoint.com text to HTML. This direction was impossible. Nothing I was trying would even work. I knew that I could trick sharepoint into reading a Choice field, but this turned out only to be true when it was single select.

So to get started I had to create my choice multiple select field.
“WorkType” – When this is first created it must be created as a single line of text.

“calc” – Second field is a calculated field =[WorkType]

Delete “WorkType”

Create new field
“WorkType” choice, multiple select

The “calc” field now will read the the string from “WorkType” the output will be something like this
;#Choice1;#Choice 3;#

The next set of fields depends on the number of options you have. My demo has 5 options (opt1-5) so I created 5 calculated fields

opt1 =IF(FIND(“Choice 1″,[calc]),”Choice 1″,”")
opt2 =IF(FIND(“Choice 2″,[calc]),”Choice 2″,”")
opt3 =IF(FIND(“Choice 3″,[calc]),”Choice 3″,”")
opt4 =IF(FIND(“Choice 4″,[calc]),”Choice 4″,”")
opt5 =IF(FIND(“Choice 5″,[calc]),”Choice 5″,”")

The formulas are searching the string (in [calc] for a specific value. When you setup yours Choice 1 would be your option 1, same thing for the returned value if true.

This returns the values in each column as it should , but the find formula returns #VALUE! it the formual is false like this:
results

I could not figure out a way to remove the #VALUE!. So I deciede to go with a string replace.

<script type="text/javascript">
var theTDs = document.getElementsByTagName("TD");
var i=0;
var TDContent = " ";
while (i < theTDs.length)
{
  try
  {
    TDContent = theTDs[i].innerText || theTDs[i].textContent;
    if (TDContent.indexOf("#VALUE!") == 0)
    {
      theTDs[i].innerHTML = TDContent.replace(/#VALUE!/,"").replace(/#VALUE!/g,"");
    }
  }
  catch(err){}
  i=i+1;
}
</script>

This looked very clean and the options are displayed in individual column in order.
results

Who said I dead, who said I’m gone!


I know it has been a while since my last post. Much has taken place. I began rebuilding a home and I have started a new job. After my first day at the job I am excited to dig further in. I have dabbled in the SharePoint platform for 7 years now. I have developed several InfoPath forms and created much customization to the SP UI and enjoy this work, but at my last p[osition this was lacking. The tasks I was getting assigned were no where near the type of challenge I need.

In my current role it almost appeared to be too good to be true. It is the kind of work I enjoy all the time. I almost feel like I get to play, and I am paid for it. After my onboarding session I was given and InfoPath form near completion. The original creator had been pulled into other priorities and not able to complete the form functionality. The issue was related to a simple dynamics. When specific conditions are meet an Approval field needs to display. On initial my thoughts of this I figured this was fairly simple, but the author explained that he had been down this path and he felt the issue had something to do with the userName() function in InfoPath returning a case difference in the account name from SharePoint People Picker. During testing within the company 2 user names were getting this issue and the field dynmamics were not working properly.

Follow

Get every new post delivered to your Inbox.