Archive for March 17, 2012

Dynamically load JavaScript file

Sometimes you don’t always want a JavaScript file to load. If, for instance, a control that utilises it is loaded by a page that already references the same JavaScript file, you wouldn’t want to load the script file again.

Note: This being a SharePoint blog, the script shown here is tailored for that platform but will quite easily port to other non SharePoint sites.

A good example of this would be a custom SharePoint WebPart that uses jQuery. Now, say you don’t have control over the page that will host the WebPart and therefore can’t guarantee that the jQuery script will be present in the page\master page\delegate header control. You could dynamically load the script file as the WebPart loads. The problem with this is that the rendering page might already be loading the same script.

Also, by loading the jQuery script file, especially in an environment you have little control over (maybe a WebPart you developed, which is used by many different systems and configurations) you could potentially cause a conflict on the use of the $ alias, which jQuery creates by default.
Read more

Get List Items by Field Value

SharePoint Short #6
To retrieve all SPListItem objects that have a specified field value, instead of writing a CAML query, use the following LINQ statement:

public List<SPListItem>  GetItemsContainingValue(SPList list, Guid fieldId, string match)
{
    List<SPListItem> matchingItems =
        (from SPListItem listItem in list.Items
         where
             listItem.Fields.Contains(fieldId) &&
             listItem[fieldId] != null &&
             listItem[fieldId].ToString().Equals(match, StringComparison.InvariantCultureIgnoreCase)
         select listItem).ToList<SPListItem>();
 
    return matchingItems;
}

Validation of viewstate MAC failed in AddWrkfl

I recently added a delegate control to a SharePoint solution. The delegate control was used to dynamically insert a custom user control into the master page. Part of the functionality of this control required the use of hidden fields.

Everything worked perfectly until I tried to add or update a workflow against a list. After clicking Next on the add workflow page, the following error was thrown:

Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that configuration specifies the same validationKey and validation algorithm. AutoGenerate cannot be used in a cluster
Read more

Disable SharePoint PeopleEditor

SharePoint Short #5
If you have a requirement to disable the PeopleEditor in SharePoint through JavaScript, the following script will do this for you:

function togglePeopleEditor(editor, enable) {
    // Disables the control but still allows the user to type into it.
    editor.attr('disabled', enable ? '' : 'disabled');
 
    // Previous control is div element, used to control the textarea control
    var editorDiv = editor.find('textarea').prev();
 
    // When not enabling, ensure text shown in people picker has been resolved, otherwise clear it
    if (!enable) {
        var entityData = editorDiv.find('#divEntityData');
        if (entityData != undefined) {
            if (entityData.attr('isresolved') == undefined || entityData.attr('isresolved') == 'False') {
                editorDiv.html('&nbsp;');
            }
        }
        // Hide any error messages
        editor.find('.ms-error').css('display', 'none');
    }
 
    // Hide any errors from view when the people editor is disabled
    if (!enable) {
        editor.find('.ms-error').css('display', 'none');
    }
 
    // Set text colour to Grey so that the control appears disabled in Firefox
    editorDiv.css('color', enable ? 'windowtext' : 'Grey');
    editorDiv.attr('contentEditable', false);
 
    // Ensure all child span elements display correct text colour and disable or enable content editing
    editorDiv.find('span').each(function () {
        $(this).css('color', enable ? 'windowtext' : 'Grey');
        $(this).attr('contentEditable', enable);
    });
 
    // The following will enable or disable the 'Check Name' and 'Browse' links.
    editor.find('a').attr('disabled', enable ? '' : 'disabled').css('cursor', enable ? 'pointer' : 'default');
    // Toggle the child anchor element event handlers
    editor.find('a').each(function () {
        if (enable) {
            if ($(this).attr('onclick') == null)
                this.onclick = $(this).data('onclick_data'); // Restore previously deleted click event
        }
        else {
            if ($(this).data('onclick_data') == undefined)
                $(this).data('onclick_data', this.onclick); // Store click data before removing the current event
            $(this).removeAttr('onclick');
        }
    });
}

Important aspects of the script are:

  • Setting the contenteditable attribute of the div (id is postfixed _upLevelDiv) that immediately precedes the textarea control to false will disable the control and not allow the user to type directly into it.
  • Removing un-resolved text from the people picker when disabling – this stops validation errors
  • Removing the onclick event handlers when disabled and restoring when re-enabling – this is only required for Firefox as other browsers do not fire the event as the parent control is set to disabled.

It should be noted that the people picker control this script assumes only one user or group, if allowing more you’ll need to update the logic for clearing the content when disabling to handle multiple entities.

Follow

Get every new post delivered to your Inbox

Join other followers: