4.04.2017

How to Automatically Shutdown Expensive Development Resources on AWS

Put this into a Lambda function and activate it using CloudWatch, and any EC2s with a tag of AutoShutdown: "true" will be shutdown when this is run!


import boto3
region = 'us-east-1'

ec2 = boto3.resource('ec2', region_name=region)

filters = [
    {
      'Name': 'tag:AutoShutdown',
      'Values': ['true']
    }
]

def getInstanceName(instance):
    for tag in instance.tags:
        if tag["Key"] == "Name":
            return tag["Value"]

def lambda_handler(event, context):
    for instance in ec2.instances.filter(Filters=filters):
        instance.stop()
        print getInstanceName(instance)  + " stopped"

10.29.2015

Developing an Angular Web App inside of SharePoint: Part 1 - Hello World in SharePoint

Angular is currently my favorite JavaScript Library. It feels like a marriage of the best of Desktop Development with the best of Web Development. It paves the way to understanding mobile and responsive design. Data-binding makes managing data on your page much more simple than the event-driven style of jQuery. Routing makes lazy-loading the pages of your app quicker and it makes spinning up new pages for your app quicker and easier as well.

(I tend to be verbose in my writing. Look for "tl;dr;" for "too long, didn't read" summaries of sections.

The Sales Pitch on using Angular in SharePoint

If you are not already sold on the idea of drinking the Angular Kool-Aid, let me go into some reasons why you should. I have 5 years of server-side SharePoint development in 2007 and 2010 (less in 2013). When we had the ability to write farm solutions on the server, doing anything in JavaScript felt like peasant-work. We avoided it at all costs. When the idea of "single-page-apps" came along, we scoffed at it as unnecessary. When we heard that SP2013 would switch to a greater emphasis on client-side development (JavaScript) we cringed. JavaScript is terrible ... why would we want more of it?

Later, I switched to a contract where deploying anything to the server was more trouble than it was worth because of environmental and contracting issues. Out of necessity, I went down the JavaScript path and haven't turned back. When I came across Angular, I realized my decision was the correct one. SharePoint is slow and it is often deployed in environments with an equally slow intranet and on computers that should were already obsolete 2 years before they were purchased as employee workstations. Ever time you click a link in SharePoint, you load about 1-2 dozen JavaScript files, some aspx files, web parts, a few css files, etc. Each of these has to be downloaded (or checked against the cache) and loaded into memory and processed. Most of these files were the same ones you just had on the last page you were on!

Angular Fixes a lot of this problem with routing. When we go into routing, we will be trading out the default Angular-routing library with angular-ui-router, which is far superior. I'll go more into that later. Routing allows you to load up your entire Angular Web App, after which, you can go to different pages within your App (called views) WITHOUT reloading all those pesky JS files. This lazy-loading means that you're only loading a very small amount of data when you switch pages. You will also learn to use promises and asynchronous web service calls to load your pages before you have the data you need on the page, so the page will load quickly. The data will then follow onto the page a moment later, and using some subtle animation, the user will have no idea that he waited any time at all.

My last sales pitch will revolve around data-binding, which does not provide a specific advantage over SharePoint, but is just a really awesome and structured way of writing your code. Data-binding will make managing complex amounts of data far-easier than you are probably use to. If you've already used other data-binding frameworks like knockout then you will know what I'm talking about. Knockout is great, and I've used it, but the syntax in Angular is far friendlier. However, the friendliness of Angular's syntax comes at a cost: it may take a little longer for you to figure out how Angular works under the hood because so much is done for you.

Getting Started with a Hello World Example

At this point, I will assume that you are already sold on the idea of bringing the power of Angular to your SharePoint site. I'll bring up the advantages of doing so, less as an attempt to convince you of those advantages, and more to help you recognize when you are adding value for your customers when you write a site. I'll also assume that you have some experience with SharePoint, though I'll assume a very low amount of experience with Server-side development and Client Side Object Model (herein referred to as either CSOM or JSOM. You will here JSOM more often when there is a danger of confusing JavaScript CSOM with C# CSOM, and the two need to be distinguished). Lastly, Bootstrap will be referenced a lot at a basic level. This really just means that we will be using pre-defined bootstrap classes that work well with Angular.

To get started, we need to create a main page that contains the minimum that is required to hook into SharePoint and allow HTML5 on the page. Start by adding a folder in Site Assets, or really any library or location on your site. Keep everything you need for your application contained in a single folder that you can copy easily. This helps with branching, so you can have a dev branch you're working on, previous versions you've saved, and a production branch that users will ultimately use.

Next, add an aspx file (or any file type and rename it to .aspx). It is necessary for your home page to be aspx and not html because this allows you to add a key asp control that is used to interact with SharePoint. This allows SharePoint to know your username and provide a SharePoint Context Object. If you've done server side development then the bit about a SharePoint Context Object will make sense to you. If not, don't worry about it.

The code snippet below includes the minimum that is required to have a SharePoint-hosted HTML5 page that can access SharePoint resources as the current user. Credit goes to all that js, and is modified to include support for Angular and Bootstrap.

 
<!DOCTYPE html>
<%@ Page language="C#" %>
<%@ Register Tagprefix="SharePoint" 
     Namespace="Microsoft.SharePoint.WebControls" 
     Assembly="Microsoft.SharePoint, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %>
<%@ Import Namespace="Microsoft.SharePoint" %>
<!--Example from: http://allthatjs.com/2012/04/03/using-sharepoint-csom-in-html5-apps/-->
<html>
<head>
<meta name="WebPartPageExpansion" content="full" />
 <!--I don't remember what each of these does exactly, but they were all necessary for one reason or another-->
 <meta http-equiv="X-UA-Compatible" content="IE=edge;chrome=1" />
 <meta name=GENERATOR content="Microsoft SharePoint">
 <meta http-equiv=Content-Type content="text/html; charset=utf-8">
 <meta name="viewport" content="width=device-width, initial-scale=1"> <!--Required for viewport commands in css. Responsive Design-->
 
 
  <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
    <!--[if lt IE 9]>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/respond.js/1.4.2/respond.min.js"></script>
    <![endif]-->   

    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">

    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.1/angular.min.js"></script>
</head>
<body ng-app="main-app" ng-controller="master-model">
    <SharePoint:FormDigest ID="FormDigest1" runat="server"></SharePoint:FormDigest>
    
    
    <!-- Begin Custom Section. Everything outside of this section should be included in any SP/Angular page that you start, minus any custom js/css I may have added -->
  <h3>{{data.message}}</h3>
 <p>{{data.site.title || 'Loading Site Details...'}}</p>
    <input id="description" class="form-control" type="text" ng-model="data.site.description" placeholder="Description">
    <p>{{data.user.username}} <a href="mailto:{{data.user.email}}">{{data.user.email}}</a></p>
   <button type="button" class="btn btn-default" ng-click="data.toggle = !data.toggle">Toggle Me!</button>
    <!-- Really good example of how you should be debugging -->
    <pre>{{data | json}}</pre>   
    <!-- End Custom Section -->
   
    
    <!-- Put all your js at the bottom so the page loads faster. Put angular at the top so it can start sinking its hooks earlier-->    

 <!-- the following 5 js files are required to use CSOM -->
    <script src="/_layouts/1033/init.js"></script>
    <script src="/_layouts/MicrosoftAjax.js"></script>
    <script src="/_layouts/sp.core.js"></script>
    <script src="/_layouts/sp.runtime.js"></script>
    <script src="/_layouts/sp.js"></script>
    
    <!--Using CDNs for demo purposes -->
    <script src="https://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.0-beta.1/angular-animate.js"></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap-tpls.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular-ui-bootstrap/0.14.3/ui-bootstrap.min.js"></script>
    <!-- include your app code --> 
    <script src="app.js"></script>
</body>
</html>

Next, set your app.js to the following:

 
(function(){
angular.module('main-app',['ngAnimate']).controller('master-model', ['$scope', '$q', function($scope, $q){
 function init(){
  $scope.data = { //Initialize data
   message: "Welcome to Angular!"
  }; 
  
  getSiteInformationUsingPromise().then(function(results){
   $scope.data.site = results.site;
   $scope.data.user = results.user;
  });


 } 
 
 function getSiteInformationUsingPromise(){
  return $q(function(resolve, reject){
   //Note that if you aren't using a master page, you can't just use $().SPServices.SPGetCurrentSite(). You have to use a relative path, not an absolute path which this function returns
   var ctx = new SP.ClientContext("/"); //This needs to include the entire relative path, included any site collections and subsites. This example uses the root site collection.
   var web = ctx.get_web();
   var user = web.get_currentUser();
   ctx.load(web);  
   ctx.load(user);
   ctx.executeQueryAsync(Function.createDelegate(this,
    function() {
     resolve({ //Angular knows to refresh the page after resolve is executed because we used an Angular Promise
      site: {
       title: web.get_title(),
       description: web.get_description()
      },
      user: {
       id: user.get_id(),
       username: user.get_title(),
       email: user.get_email()
      }
     })     
    }), Function.createDelegate(this, function(sender, args) {
     reject({
      title: 'Error'
     })
    }));
  });
 }

 
 init();
}]);
})();

There you go! This should be a basic Angular page with a minimal tie-in to SharePoint. In my next post I intend to expand further and eventually break the data-access layer out into a separate module as an Angular Factory. I'll also do some simple CRUD operations. In the mean time, look over the code and take note of many of the comments which drill down into a little more detail about why I'm doing things certain ways.

6.24.2015

Self-Expiring Comment Pattern

As a developer, having good style is important to me. I can’t tell the number of times I’ve inherited code, and wondered what the heck was going on. I can’t tell the number of times I’ve looked at code I’ve written six months ago and wondered what the heck was going on.

In school, I was taught to comment EVERYTHING. I don’t think this was the right lesson, as we would often comment functions with self-commenting names. There is no reason to add comments to a function called "public Item GetItemById(int ID)" in my opinion.

In any case, I have made it a point to comment any code that I didn’t think had an obvious function. I also, like many people, tend to comment obsolete code instead of deleting it. This can often result in a source file in which sometimes half of the file is commented out functions. This is even harder to read than a file with no comments.

So what I’ve come up with is the Self-Expiring Comment Pattern. I think it is simple enough, and I have used it long enough, that I’m ready to see what people think of it. I’ll use JavaScript for my example:

 
//Todo: Delete Commented Code after 9/24/2015 or after Sprint 5
/*function oldFunction(){
}*/

//Todo: Delete comment after 9/24/2015 or after Sprint 5
//This seems to work better than oldFunction because of x, y, and z
function newFunction(){
}

The concept here is super simple. If I am looking at this code that I just inherited on week 2 of my new job, and I see these comments, I don’t even have to read them. I know they are safe to delete, and I don’t have to worry that I’m breaking anything or deleting important reference code by doing it. This is sort of a pass-the-buck approach that we are probably already aware of as developers. You would do this when you have a comment that just reflects what you are thinking about right now, but you know will not be useful once you're finished with this section of code, or when the current build is deployed. You don't have to be too accurate with the date you pick. Just pick anything that ensures that your comment will not exist until the end of life of your code.

This works even better in Visual Studio or Eclipse, which interprets Todo comments as tasks which are gathered into a Tasks pane for easy access.

Since I’ve started doing this, I have found it easier to maintain enough comments in my code to be useful, without having so much that it becomes cumbersome. I’m going to start trying to push this concept more and more in the future. It seems like a small change, but having code that’s easy-to-read is worth it I think.

I welcome thoughts and feedback on this idea.

Update: After a few conversations, I think the consensus is that this idea is a solution to a problem that has already been solved a better way. Stick with proper version control, and this idea is not necessary. Only if proper version control is not an option should this idea be considered.

Update 2: Looks like someone has previously come up with a slightly better version of my idea called Tombstones

1.14.2014

C# Features You'll Wish that You'd Discovered Sooner: Yield

What is yield? A Brief Overview

Yield is a feature of C# that is not present in its largest competitor, Java. Many of you will have heard of it, but haven’t really used it, or have dismissed it as “syntactic sugar”. Others will have never heard of it before. In short, it is a way of replacing this:
        public static List<int> ExampleList()
        {
            List<int> ret = new List<int>();   
            ret.Add(1);                        
            ret.Add(2);                         
            ret.Add(3);                         

            return ret;                         
        }
With this:
        public IEnumerable<int> ExampleYield()
        {
            yield return 1;                     
            yield return 2;                     
            yield return 3;                     
        }

So what happened here? First, we’ve opted away from List for a more interface-driven IEnumerable function return. Also, we’ve reduced the number of lines; by 2 to be exact. And somehow, we’ve managed to return a list of items without actually allocating a new list. That’s an important point to make, because we have completely avoided instantiating a new object. What we’ve done is we have actually created an anonymous IEnumerable-implementing object in only a few lines. We’ve created an object that says “hey, let users call this method to request a bunch of stuff, but I don’t care if the stuff is a List or a dictionary or what. Also, don’t waste time allocating some new object if it isn’t necessary.” That’s the key here … we haven’t filled up a new List object with these 3 items. That means that we have no unnecessary memory footprint. We’re just returning items. But how is it doing this? Imagine this method, ExampleYield, were called like this:

        foreach (int i in ExampleYield())
        {
           DoSomething(i);
        }
Well, if we were calling ExampleList() instead of ExampleYield(), we’d load up a List object, and then return the entire thing and then operate on it. But with ExampleYield, the order that the code is run is shown in the comments of the code below:
        foreach (int i in ExampleYield())   //1
        {
            DoSomething(i);                 //3, 5, 7
        }
        public IEnumerable ExampleYield()
        {
            //Note that it is not necessary to allocate a List or any other kind of new data structure
            yield return 1;                     //2
            yield return 2;                     //4
            yield return 3;                     //6            
        }
There are a couple things to notice:

ExampleYield is not run to completion. Instead, code runs until the first yield is reached. Hopefully now you see why this is called “yield”. The ExampleYield method does not resume until another value is request by the calling foreach loop. If we weren’t using a foreach loop for the IEnumerable, this would happen when we called the MoveNext() method, and then accessed the Current property. As a result of the point made above, no new object needs to be created to hold all of these items. They’re just returned as-needed. This may not be a big deal with 3 items, but what if there were 300,000 items? What kind of memory footprint would a 300,000 item List object have? Also, if you were to run an IEnumerable method like Any() (which checks to see if the enumerable has a none-zero number of items), the ExampleYield method would run to the first line, “yield return 1;” line, and then stop. It would know the value is true, and would not have to run through the rest of the method. This would save even more time.

An IEnumerable can very easily be converted to a List, using ToList(), which would take no more time than it would have taken to create the list in the first place. There is also a ToDictionary() method, which requires a very simple lambda expression. However, this would be a business-layer-implementation decision by the calling code, rather than a data-access-layer decision in the ExampleYield method. A sufficiently intelligent compiler can use this to tell exactly what you’re trying to do. If the compiler decided that the best use of a multi-core processor is to dedicate one core to the yield method, and another core to the main code, it could do this. The dependencies are obvious when you write a yield method. However, I should mention that I don’t know the exact details of how compilers deal with yield for these purposes.


Lastly, the syntactic sugar value should not be overlooked. The method just LOOKS a lot better. It’s shorter and to the point.

A Less Obvious Use for Yield: Decorating a Collection by Wrapping Each Object

I am an advocate of wrapper objects. As a SharePoint developer, I strongly believe that no SPListItem object should ever be accessed outside of the wrapper object that is designed to contain it. Your view layer should not care that it’s dealing with a SharePoint list item. So, imagine that you agree with the last paragraph, and then imagine that you have a list called Students, and you have a business object wrapper called Student. How can you return an Enumerable of Student objects, while still leveraging the data access layer that SharePoint has provided for you? In other words, how do you perform a query on those items, without having to create a new List object to hold them? The answer is below:
        private IEnumerable PerformStudentsQuery(SPWeb Web, String Query)
        {
            SPList list = Web.Lists[StudentsList.ListName];
            SPQuery query = new SPQuery();
            query.Query = Query;

            SPListItemCollection col = list.GetItems(query);

            foreach (SPListItem listItem in col)
                yield return new Student(listItem);
        }
See what happened there? You don’t have to fill an entire List with Student objects and then return the List. You start the query, and then just yield return each list item, but then throw a wrapper around each item as it is returned. There are no wasted cycles, no wasted memory footprint, and no exposed SPListItem objects that can be misused. Just a neatly wrapped object that is wrapped as it is requested.

One More Less Obvious Use: Augmenting a Collection

Say you need to return the contents of some Data Structure. Let’s say, an array. But you need to variably add one or two static items to it.
        private static bool includeListContents { get; set; }
        private static string[] listContents = { "circle", "square", "triangle" };
        public IEnumerable ListContents
        {
            get
            {
                yield return "none";
                if (!includeListContents)
                    yield break; //This ends the method, and no more items are yielded

                foreach (string value in listContents)
                    yield return value;

                yield return "all of the above";
            }
        }
Here we’ve added a custom static string to the front and the end of a string array if IncludeListContents is true. Otherwise, we just return a single item with a value of “None”. Notice the use of “yield break;”. This ends the method (like a return might for a void function). Also worth noting is that there is an implied “yield break” at the end of any IEnumerable method, so you don’t normally need to put it in. But it can be useful for complex methods, like above. We’ve done this without modifying the array. The calling method has no idea. It just knows it got back 0 or more items, which is all it needs to know.

Infinite Data

Yield is at its most powerful as a way of consuming data that might never end. Notice that, because this is done lazily, the absolute least amount of work will be done by the CPU to accomplish this task. Obviously, this will start to fail as the number becomes too large to be handled by a long.
        IEnumerable LazyFibonacci()
        {
            yield return 0; //Return base case. Avoids having to set prev to -1, which we can't do with a ulong

            ulong prev = 1;
            ulong curr = 0;
            ulong next;
            while (true)
            {
                next = prev + curr;
                yield return next;
                prev = curr;
                curr = next;
            }
        }

Advanced Topics

You can’t put a yield return in a try/catch, but you can put one in a try/finally. Read here for a more detailed explanation as to why: http://blogs.msdn.com/b/ericlippert/archive/2009/07/16/iterator-blocks-part-three-why-no-yield-in-finally.aspx If you decide to use the Enumerator manually, using MoveNext()/Current, rather than in a foreach loop, you should be aware of problems cleaning up Disposables in your method, since the method will not be run to completion. So call Dispose() on your Enumerator when you’re done with it or open it in a using block to avoid leaving any Disposables open in an Enumerator. More information can be found here: http://blogs.msdn.com/b/dancre/archive/2008/03/14/yield-and-usings-your-dispose-may-not-be-called.aspx

To Summarize

Yield is useful in any kind of data-access layer method in which you haven’t decided what the calling method is going to want to do with the data. In other words, the majority of data-access layers. It is useful for very large amounts of data, or an infinite amount. It is useful for generalizing your data, and letting the business layer decide what specific structures to use. Yield is elegant, efficient, clean, generalized code. It lowers the potential memory footprint of your code. It reduces the number of lines, and therefore, complexity. It gives valuable information to your compiler, which can be used to further optimize your code. It allows you to easily convert a list from one type to another as items are extracted from that list, rather than having to create a new list first. It makes your code more generalized, so it doesn’t matter if you need your data as a List, a Dictionary, for a for-each, as a tree, or whatever else you may use. It’s lazy, and only does as much work as is necessary to get the job done. And you’ll find that converting your existing code to yield, or writing new code with it, is often much easier than you assume.

5.03.2013

Animating my Awesome Blog Header!

This is what I do when I have too much spare time. I'm learning how to animate Canvases with HTML 5.

Hover your mouse over the guy with the sword to see what I've done so far! By the way, the design of everything on this site is courtesy of the great work by the lovely Jennifer at Jennifer Stuart Design.
Your browser does not support the canvas tag Your browser does not support the canvas tag

4.27.2013

Fixing the Complex Dropdown Bug in SharePoint 2010

The Purpose of this Post
This post will show you how to get rid of pesky Complex Dropdowns from your SP2010 sites once and for all. If you just want the code, skip to the end. If you don't know what a Complex Dropdown is, or why you'd want to get rid of it, read the Quick Recap below.

Quick Recap
When you have a Lookup List that contains 19 or fewer items, SharePoint renders this as a normal dropdown. Simple, clean, elegant.

When your list reaches 20 items or more however, SharePoint has decided to automatically replace this simple, clean, and elegant dropdown with some messy, sloppy, and difficult-to-use Complex Dropdown. This is meant to be an upgrade. The text box, with jQuery behind it, allows users to type the item that they're looking for (which you can actually already do with a dropdown). However, in practice, it is prone to unexpected behavior:

1) You can already click on a dropdown and type, in order to search for an item. The complex dropdown doesn't add any useful functionality.
2) The dropdown doesn't always dismiss right away, forcing you to click more than once. It's slow, and not very helpful.
3) If a developer attempts to add code to pre-select a value, there are unintended side-effects that must be fixed with additional script.
4) In a recent update to SharePoint, a bug was introduced in which all Complex Dropdowns originate on the same location on the page. This means that if you have more than one dropdown on a page, all except one will appear to function incorrectly.

What are the Solutions?
In general, I don't like the complex dropdown for any reason. There are two main ways of solving this problem. This post focuses on the 2nd:
1) If you generate your forms in code using the FormField class, you can set FormField.InDesign = true; before rendering.
2) You can run JS on the page to fix everything. The original solution for this is here: An Egg in the SharePoint World

The Two Minor Shortcomings of the Solution Above
1) It fails on fields that are required to have values. A required Lookup field will automatically pre-select the first value in the dropdown. If the user doesn't change this value, the validator will mistakenly complain that they don't have a value selected. This is wrong for two reasons ... first, a value IS selected, and we probably shouldn't have pre-selected a value in the first place.

I fix this problem by adding an entry of  "Please select one..." at the top of the dropdown.

2) The second issue that this solution doesn't work with cascading dropdowns.

I fix this problem by reworking the code a little bit, and making sure that the values are written back and forth between the hidden complex dropdown, and the new simple dropdown. This is accomplished using the method updateNewField, which is commented below at the bottom of the post.

I wrap all of this into a ScriptLink feature, and simply enable this feature on any site where I don't want to see Complex Lookup Field Dropdowns. Don't know about creating ScriptLink features? More info here: SharePoint 2010's ScriptLink. This is a great way of packaging general-use solutions to problems.




The Code

// Comment
//http://stackoverflow.com/questions/11416099/sharepoint-drop-down-list-doesnt-display-properly-for-more-than-20-items-with-i

DisableComplexDropdowns.FixDropdowns = function () {
    $('.ms-lookuptypeintextbox').each(function () {
        DisableComplexDropdowns.OverrideDropDownList($(this).attr('title'));
    });

}

// Main Function
DisableComplexDropdowns.OverrideDropDownList = function (columnName) {
    // Construct a drop down list object
    var lookupDDL = new DisableComplexDropdowns.DropDownList(columnName);

    // Do this only in complex mode...
    if (lookupDDL.Type == "C") {
        // Hide the text box and drop down arrow
        lookupDDL.Obj.css('display', 'none');
        lookupDDL.Obj.next("img").css('display', 'none');

        // Construct the simple drop down field with change trigger
        var tempDDLName = "tempDDLName_" + columnName;
        if (lookupDDL.Obj.parent().find("select[ID='" + tempDDLName + "']").length == 0) {
            lookupDDL.Obj.parent().append("");

            var newDDL = lookupDDL.Obj.parent().find("select[ID='" + tempDDLName + "']");
            $(newDDL).bind("change", function () {
                DisableComplexDropdowns.updateOriginalField(columnName);
            });
        }

        DisableComplexDropdowns.updateNewField(columnName);
    }
};

// method to update the original and hidden field.
DisableComplexDropdowns.updateOriginalField = function (columnName) {
    var lookupDDL = new DisableComplexDropdowns.DropDownList(columnName);
    var newLookupDDL = new DisableComplexDropdowns.DropDownList("tempDDLName_" + columnName);

    // Set the text box
    if (lookupDDL.Obj.val() != newLookupDDL.Obj.find("option:selected").text())
        lookupDDL.Obj.val(newLookupDDL.Obj.find("option:selected").text());

    // Get Hidden ID
    var hiddenId = lookupDDL.Obj.attr("optHid");

    // Update the hidden variable
    if ($('input[name=' + hiddenId + ']').val() != newLookupDDL.Obj.find("option:selected").val())
        $('input[name=' + hiddenId + ']').val(newLookupDDL.Obj.find("option:selected").val());
};

//Call this method from the completefunc in SPServices.SPCascadeDropdowns like so:
//completefunc: function(){
//                if (typeof DisableComplexDropdowns != "undefined" && typeof DisableComplexDropdowns.updateNewField != 'undefined') {
//                    DisableComplexDropdowns.updateNewField(controlTitle);
//                };}
DisableComplexDropdowns.updateNewField = function (columnName) {
    var lookupDDL = new DisableComplexDropdowns.DropDownList(columnName);
    var newLookupDDL = new DisableComplexDropdowns.DropDownList("tempDDLName_" + columnName);

    if (newLookupDDL == null)
        return;

    // Get all the options
    var splittedChoices = lookupDDL.Obj.attr('choices').split("|");

    //If this is a required field, leave a "null" option at the top so that nothing is pre-selected
    if (splittedChoices[1] != "0") {
        splittedChoices.unshift("Select One ...", "0");
    }

    //Determine if the dropdowns are the same. If so, return without changing anything
    var i = 1;
    var different = false;
    newLookupDDL.Obj.children().each(function () {
        if ((i + 1) > splittedChoices.length) //Current dropdown has more items than the old dropdown
            different = true;
        if ($(this).val() != splittedChoices[i])
            different = true;
        i++;
        i++;
    });

    if (!different && (i - 1) == splittedChoices.length)
        return;

    // get selected value
    var hiddenVal = $('input[name=' + lookupDDL.Obj.attr("optHid") + ']').val()
    if (hiddenVal == "0") {
        hiddenVal = lookupDDL.Obj.attr("value")
    }

    newLookupDDL.Obj.children().each(function () {
        $(this).remove();
    });

    // Populate the drop down list
    for (var i = 0; i < splittedChoices.length; i++) {
        var optionVal = splittedChoices[i];
        i++;
        var optionId = splittedChoices[i];

        var selected = (optionId == hiddenVal) ? " selected='selected'" : "";
        newLookupDDL.Obj.append("");
    }
};

// just to construct a drop down box object. Idea token from SPServces
DisableComplexDropdowns.DropDownList = function (colName) {
    // Simple - when they are less than 20 items
    if ((this.Obj = $("select[Title='" + colName + "']")).html() != null) {
        this.Type = "S";
        // Compound - when they are more than 20 items
    } else if ((this.Obj = $("input[Title='" + colName + "']")).html() != null) {
        this.Type = "C";
        // Multi-select: This will find the multi-select column control on English and most other languages sites where the Title looks like 'Column Name possible values'
    } else if ((this.Obj = $("select[ID$='SelectCandidate'][Title^='" + colName + " ']")).html() != null) {
        this.Type = "M";
        // Multi-select: This will find the multi-select column control on a Russian site (and perhaps others) where the Title looks like 'Выбранных значений: Column Name'
    } else if ((this.Obj = $("select[ID$='SelectCandidate'][Title$=': " + colName + "']")).html() != null) {
        this.Type = "M";
    } else
        this.Type = null;
}; // End of function dropdownCtl


if (typeof $ != 'undefined') {
    $(function () {
        DisableComplexDropdowns.FixDropdowns();
    });
}