Thursday, August 11, 2016

How to Add a Spacer to a CRM Business Process Flow

The CRM form designer has a Spacer feature, that allows for having blank spaces where normally fields are required.  This feature is sorely missing in CRM Business Process Flows, but the good the news is that you can implement your own space with no coding required!  Just to be clear about what I’m talking about, here is a picture, showing how the Sub-Total should be over the Tax Amount and Total Amount:
BPF
This requires two simple steps:
  1. Add a field to the BPF where the space is desired, that doesn’t and exist in the BPF and will never need to be displayed anywhere on the form,  I’ll use “Created By (Delegate)” in this example, but you could always create your own:
    BPF-Designer
  2. Create a business rule that always hides the field:
    image

Now, when the form loads, the Business Rule will hide the field, allowing it to serve as a spacer:
BPF-Blank

Monday, August 8, 2016

Pick a Mountain, Any Mountain

For just being larger than average piles of dirt and rock, mountains can do and cause extraordinary things in an individual’s life.  Last year, in celebration of our 10 year anniversary, my wife and I decided to climb Pike’s Peak.  It’s a 13 mile journey from Manitou Springs, CO, rising up 7800 feet, past the tree line, half way to the stratosphere.  It’s a hike made difficult by its length, incline, and diminished levels of oxygen (especially for someone from oxygen rich Indiana) at the top of the 14,118 foot mountain.  So why would anyone want to climb it?  My answer was the same as the standard answer pertaining to mountains, “Because it’s there.”
Distant Pikes Peak
Pike’s Peak posed a challenge for me.  It forced me to face something I had never done before, with no guarantee that I could even accomplish it.  Once the goal was set, it required my wife and I to make plans, buy tickets, comprise arrangements for the kids, and prepare for the challenge months before hand.  For months, we consumed and were consumed by everything we had available to us about the journey, multiple blog articles/videos about the journey, where to rest, where to get water, what to wear, what to bring, where to park, and what potential emergencies to prepare for.  We learned from other’s mistakes, and envied those that had already completed the journey.

When we arrived in Manitou Springs, we were simultaneously excited and daunted by the shear size of the mountain.  We met first hand, both those that had made the trek, and those that had lived in Colorado their whole lives, and only ever drove to the peak, eagerly anticipating that we would be included in the former group, rather than the later.

The morning of the hike, we left our hotel at 3 am and arrived at the base, in near total darkness, turned on our flashlights, and started climbing.   We were making great time and arrived at Barr Camp, slightly ahead of schedule.  After a quick bite to eat and some water to drink, we continued our ascent.  Things continued to go well until after we passed the tree line.   The unseen diminished oxygen levels started to slowly take its toll.  There had been few rests/stops up until that point, but shortly thereafter, I started requiring more and more breaks to catch my breath.  The final 2 hours of the climb saw me stopping every 10-40 feet to catch my breath, and sitting down every 200-400 feet in an attempt to regain the energy/strength in order to continue forward. 

It was at this point, when I was the closet to accomplishing the goal I had set out for myself months before hand, that I began to seriously question whether I would be able to finish.  It was at this point, that my wife stopped becoming a companion on the trip, and started to become a slave driver cheerleader.  At this point in time, I should probably explain some of the physical differences between my wife and I.  My wife is an avid workout enthusiast.  She exercises most days of the week, eats healthy, and runs half-marathons (3 of which at 4, 5 and 7 months of pregnancy).  Let’s just say, she is a healthy in shape woman.  I on the other hand, managed to lose 10 pounds before the trip, but rarely work out more than twice a week, and besides a single 5K, haven’t ran a race since high school.  It is my firm belief that the last mile of the climb, she could have ran up and down 3 times, before I made it up once.  But instead, she continued to encourage and coach me up the rest of the mountain.

When we finally reached the top, I was met a rather unusual combination of emotions.  I was tired, exhausted, sore and weak.  On the other hand, I was filled with an incredible sense of accomplishment and pride, having overcome an extremely challenging task.  If my goal was to drive up the mountain, I would have been able to enjoy the same views, and the same (IMHO) below average donuts that await any visitor to the top.  Because of the difficulty of the goal, the sense of accomplishment was several magnitudes greater.  It was and is, the most difficult physical accomplishment of my life.

The TopAllegient At The Top

Last month I realized a rather large career goal, being bestowed as a Microsoft MVP Award winner.  It, as my Pike’s Peak adventure, was a goal that I had set for myself long before it became realized.  It, as my Pike’s Peak adventure, was only accomplished via the support and encouragement of those around me.  And it, as my Pike’s Peak adventure, was a goal, with no guarantee of success.  I can only attribute my success to lots of late nights and early mornings working to further the CRM community along with the support of my wife, my co-workers, and my company itself.  My wife sacrificed her time with me, allowing/encouraging/supporting me as I spent large amounts of personal time working on open source projects.  I had multiple co-workers that encouraged me to continue working towards being an MVP, and even being the direct result of why I was nominated in the first place.  Allegient, a consulting firm, and my current employer, is a company that sees value in its employee’s spending time outside of work doing things that aren’t directly related to a client or billable work.  I’m not asked or expected to consistently work 50 hour weeks, which gives me the spare time I need to contribute to the community as a whole.  They even paid for me to attend conferences like Extreme CRM where I got to meet first hand other CRM MVPs who supported and encouraged me as well.

What are your current long term goals?  What are you working for that has a high uncertainty of success?  Do you have the support from your friends/family/co-workers/company to accomplish them?  What mountain are you climbing?  Pick a mountain, any mountain, and don’t stop until you reach the top!

Tuesday, July 26, 2016

GetClientContext Is Not Defined When Navigating Back To WebResource Html File

Ran into an interesting issue with chrome caching the ClientGlobalContext.js.aspx, and not providing an Xrm context to my javascript, when using the browser to navigate back to my webresource.  So just to clarify:
  1. Hit custom html WebResource via browser.
  2. WebResource loads ClientGlobalContext.js.aspx via script tag:
    <script src="../../ClientGlobalContext.js.aspx" type="text/javascript"></script>
  3. WebResource Displays link to CRM Entity.  Navigate to CRM Entity via link.
  4. Click “back” button in browser to navigate back to the custom WebResource.
  5. Receive JS error:
    GetClientContext is not defined
So, what’s going on?  Opening up the Developer Tools / Network tab on the initial load shows how it’s supposed to be working:


The first line is the load from the custom WebResource.  The second line, is then the ClientGlobalContext.js.aspx, loads itself, but as an xhr, rather than a script.  This loads the Xrm Context.
But when I look at the Network Tab when when I get the error: this is what I see:





The ClientGlobalContext.js.aspx is being loaded from cache.  That’s a good thing normally, but it never actually executed the xhr request.  Why Not?  When I opened the cached document, it was actually the xhr that was cached:


So how do I prevent the xhr from getting cached over the top of the script version?  Just append a query string to the end of the aspx page:
<script src="../../ClientGlobalContext.js.aspx?type=script" type="text/javascript"></script>
That way, the files can get cached separately…

Wednesday, September 16, 2015

There And Back Again, A Tale Of Three Jobs, Six Months, And Never Leaving The Building

Ding!  My inbox announced another grand arrival of the third LinkedIn recruiter e-mail of the day, and it was only 10 am.  Most LinkedIn job opening blasts are for positions I’m not qualified for, in locations I do not want to move to, or involve travel, or I just plain am not interested in, but this one was a little different.  It felt like someone looked at my resume and created a position directly from it.  Doing a quick review I discovered that the two other job offers happened to be for the same exact position, but from two different recruiting firms.  I didn’t have any desire to leave my current company, but with a job description so specifically tailored to me, with some leadership opportunities I didn’t foresee myself having in the near future, I decided to investigate it a little further.
The next few weeks were a blur with phone/Skype interviews, lots of questions, weekend conversations with a potential new boss, and promises of exciting new experiences and leadership opportunities, I made the leap.  I didn’t have to leap very far though, the new company was in the same building, just one floor higher.  And so, with high expectations and the excitement that comes with a new start, I climbed the extra flight of stairs to my new job, my new cube, and my new co-workers.
I enjoyed the challenge of the new leadership opportunities (although not as much as I hoped I would) and really enjoyed what I got to work on, but that is where the positives of the new position ended.  I’m not going to go into the details here, but let’s just say that I was more than a little curious when 6 months later, an Allegient recruiter sent me an e-mail about a potential new position.  I had to stop and think, was it something I was interested in?   I don’t know if it’s most men, most developers, or just me, but I don’t have a strong grasp of what I’m feeling at a given moment in time.  When I come home from work and my wife asks, “How was your day”, or “How do you feel”, I have to stop and think about it, because I have no immediate feelings on either subject.  I’m a thinker, not a feeler.  So how do I compare the Apples of Oranges of being a consultant to being an employee?  This is when I bring in Scott Hanselman’s tried and true Dream Job Diagram:
I ran through a quick mental check list.  I felt like I was good at both positions and I knew that I would equally love what I would be working on.  I remember thinking to myself, “It really looks like its a tie… but if that’s true, why do I feel such a desire to go back?”  The “feeling” part of my brain responded immediately and rather unexpectedly with the answer, “It’s the people”.  For the past 6 months I had been working with extremely capable and competent people, but failed to enjoy actually working with them.  I realized that my Allegient Co-workers had made work fun and exciting, and something I would look forward to each day.  So the next day I called my boss and put in my two weeks notice and have yet to regret it since.
How about you dear reader?  Are you in your “Dream Job”, being paid to do what you love and are good at, surrounded by people that make it all the more enjoyable?  If you answered no, then do yourself a favor and checkout our current job postings.  The “feeling” part of your brain may just thank you later.   

Thursday, August 20, 2015

How To Fix Workplace And Resource Center Icons In CRM 2015.1

CRM 2015 Update 1 removed the workplace and Resource Center from the site map.  It also replaced all the existing icons that were still in use.  By default this gives a very poor looking sitemap:


Here is how to update the icons to give a much more polished look:

  1. Create or find the icons that you want to use.  The new CRM Icons are 85x71, so you’ll want to follow that standard for optimal display.  (You can download my icons here.  I made them myself.  Feel free to donate using the Donate button on the right.)
  2. Upload the icons as web resources (The XrmToolBox has a great plugin for this, or you can do it manually).  Record the name you give for each icon.
  3. Download and run the XrmToolBox.
  4. Open the SiteMap Editor plugin, and login to the CRM instance to be updated.
  5. Click the “Load SiteMap” button to load the site map from CRM.
  6. -Optional- Click “Save SiteMap” to make a backup incase the changes made need to be reverted.
  7. Click on the “Area (Workplace)” node and update the Icon path to the path of the appropriate web resource. image
  8. Click Save.
  9. Click on the “Area (ResourceCenter)” node and update the Icon path to the path of the appropriate web resource.
  10. Click Save.
  11. Click “Update SiteMap” to push the changes.
  12. Stop staring at the old nasty blown up 32x32 icons in your SiteMap.

Monday, July 13, 2015

How To Display A Web Resource In CRM 2015 Without Loosing Column Width

I was recently adding JavaScript to display an iFrame when the fields required by the web resource had been populated on the form.  I noticed that the width of the iFrame was getting squished when it was being displayed:

Default:
Before


After calling setVisible():
After


It took some time stepping through the CRM libraries to figure out what was going on, but I believe it to be a bug within CRM (having the same issue?  Upvote this ticket!)  By default, CRM will attempt to update the CSS Table-Layout of the control when setting it’s visibility.  The fix is unsupported, but resolves the re-sizing issue.  After setting the visibility, check to see if the control is an iFrame, and the visibility is true.  If so, update the css of the parent table to be “fixed” *UPDATE 7/14/2015* Also need to set the height if there is a data-height attribute specified.

if (controlName.indexOf("IFRAME") >= 0 && visibility) {
    // https://connect.microsoft.com/dynamicssuggestions/feedback/details/1541195
    // THIS IS A FIX FOR A BUG WITH CRM WHEN SETTING IFRAMES AS VISIBLE.
    var ctrl = $("#" + controlName + "_d");
    ctrl.parents("table").last().css("table-layout", "fixed");
    var height = ctrl.attr("data-height");
    if (height) {
        // Set the height if defined
        ctrl.css("height", height + "px");
        ctrl.css("padding-bottom", "0");
    }
}

Friday, April 24, 2015

How To Ignore Mismatch Processor Architecture Warnings In Unit Test Assemblies With Faked Assemblies

I was attempting to cleanup the warnings in our solution build and ran into this one:
There was a mismatch between the processor architecture of the project being built "MSIL" and the processor architecture of the reference "Microsoft.TeamFoundation.WorkItemTracking.Client.DataStoreLoader", "x86". This mismatch may cause runtime failures. Please consider changing the targeted processor architecture of your project through the Configuration Manager so as to align the processor architectures between your project and references, or take a dependency on references with a processor architecture that matches the targeted processor architecture of your project. [C:\_Dev\Current Sprint\Xrm.Common.Tests\obj\Debug\Fakes\xrmt\f.csproj]    Xrm.Common.Tests
Researching the error on the web I found that I should be able to use the ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch Project property to ignore the warning.  I added the property to my Unit Test project and it didn't do anything.  After searching for another 20 minutes I ended up re-reading the warning, and noticed that it was referencing a csproj file other than the one that VS was showing as containing the warning. 
A couple more tests and I finally found that you can include MSBuild properties in the Fakes csproj by using the Compilation Element:
<Fakes xmlns="http://schemas.microsoft.com/fakes/2011/">
  <Assembly Name="Xrm.Common"/>
  <Compilation>
    <Property Name="ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch">None</Property>
  </Compilation>
</Fakes>

Problem Solved!

Now on to clearing out the rest of the warnings...