Sunday, June 26, 2011

Keep Your Android Running All Day

I just wrote and published a little guide to help keep your Android-powered smart phone running all day without charging. http://amzn.to/mE4sFe

It is currently only available in Kindle but the hard copy will be available soon.

Thursday, March 24, 2011

IMNRC in UpdatePanel - Postback Issue Resolved

Issue Premise
When using IMNRC within an Ajax based UpdatePanel, the Communicator/Lync presence appears fine upon initial load. Once a post back occurs, the presence indicators render as offline images and the communication menu is not available. This is the exact issue discussed in the Microsoft forums here.

Scenario
I created a tabbed version of the Smart Part web part. This tabbed version renders various configurable tabs, and just like the Smart Part, loads the selected aspx user control. I use an UpdatePanel to load the controls and perform partial post backs when a different tab is selected.

One of the controls I created for use within this tabbed web part is a list of users based on certain filters or criteria. I generate the users using the presence image calling the IMNRC javascript function within the onload parameter. As described in the Issue Premise, upon initial rendering, the indicators function normally. When I click on a different tab and then come back to the list of users, all of the images go "offline" and there is no more drop-down menu available.

Root Cause
The root cause lies within the IMNRC function during a postback. The objects are not set properly for conditions to render the proper code. The orginal poster of the problem found that commenting out a condition in the IMNRC function allowed the presence to persist upon postbacks. I was able to reproduce his solution and it did work but I noticed that even though the indicators showed the users' status, I no longer had the communicator menu after a postback. So the loss of functionality as well as the editing of system javascript would not work for me.

Solution
My solution involved four steps:

1) Copying and tweaking the IMNRC function to handle postbacks
2) Renaming the IMNRC function to something else (e.g. CustomIMNRC)
3) Including the new function in my control markup or including in a referenced custom .js file
4) Modifying the onload parameter of the img tag to use the new function name.

The tweaking of the IMNRC function involves creating a new variable named postback and setting that to true:

var objSpan = obj;
var id = obj.id;
var fFirst = false;
var postback = true;


Next change the fFirst variable to postback in one of the lower if conditions:

if (postback && EnsureIMNControl() && IMNControlObj.PresenceEnabled) {
var state = 1, img;
state = IMNControlObj.GetStatus(name, id);

....
Finally add || postback to the last if (fFirst) condition: {this block of code allows the communicator menu to appear over the image when moused over}

if (fFirst || postback) {
var objRet = IMNGetOOUILocation(obj);
objSpan = objRet.objSpan;

...
The full function is show below: (use it in as script in your markup or include in a reference .js file)

function CustomIMNRC(name, elem) {
        if (name == null || name == '')
            return;
        if (browseris.ie5up && browseris.win32) {
            var obj = (elem) ? elem : window.event.srcElement;
            var objSpan = obj;
            var id = obj.id;
            var fFirst = false;
            var postback = true;
            if (!IMNDictionaryObj) {
                IMNDictionaryObj = new Object();
                IMNNameDictionaryObj = new Object();
                IMNSortableObj = new Object();
                IMNShowOfflineObj = new Object();
                if (!IMNOrigScrollFunc) {
                    IMNOrigScrollFunc = window.onscroll;
                    window.onscroll = IMNScroll;
                }
            }
            if (IMNDictionaryObj) {
                if (!IMNNameDictionaryObj[id]) {
                    IMNNameDictionaryObj[id] = name;
                    fFirst = true;
                }
                if (typeof (IMNDictionaryObj[id]) == "undefined") {
                    IMNDictionaryObj[id] = 1;
                }
                if (!IMNSortableObj[id] &&
    (typeof (obj.Sortable) != "undefined")) {
                    IMNSortableObj[id] = obj.Sortable;
                    if (!bIMNOnloadAttached) {
                        if (EnsureIMNControl() && IMNControlObj.PresenceEnabled)
                            window.attachEvent("onload", IMNSortTable);
                        bIMNOnloadAttached = true;
                    }
                }
                if (!IMNShowOfflineObj[id] &&
    (typeof (obj.ShowOfflinePawn) != "undefined")) {
                    IMNShowOfflineObj[id] = obj.ShowOfflinePawn;
                }
                if (postback && EnsureIMNControl() && IMNControlObj.PresenceEnabled) {
                    var state = 1, img;
                    state = IMNControlObj.GetStatus(name, id);
                    if (IMNIsOnlineState(state) || IMNSortableObj[id] ||
     IMNShowOfflineObj[id]) {
                        img = IMNGetStatusImage(state, IMNSortableObj[id] ||
           IMNShowOfflineObj[id]);
                        IMNUpdateImage(id, img);
                        IMNDictionaryObj[id] = state;
                    }
                }
            }
            if (fFirst || postback) {
                var objRet = IMNGetOOUILocation(obj);
                objSpan = objRet.objSpan;
                if (objSpan) {
                    objSpan.onmouseover = IMNShowOOUIMouse;
                    objSpan.onfocusin = IMNShowOOUIKyb;
                    objSpan.onmouseout = IMNHideOOUI;
                    objSpan.onfocusout = IMNHideOOUI;
                }
            }
        }
    }


If you found this useful, please help support my SharePoint and .NET user group (Philly SNUG) by clicking on the logo below.

Friday, February 4, 2011

InfoPath 2007/2010: Tracking Changes in InfoPath

One of the coolest solutions in my InfoPath How-To book is the tracking of changes within a form. Although this requires code-behind the results are well worth the effort. Although my latest solution is for InfoPath 2010, you can use the same code and concepts in InfoPath 2007. My original solution was indeed in InfoPath 2007.

While writing the solution for the book, I realized I did not have the latest code and that there were some missing steps that I coded at the client site to handle line breaks. Have no fear! I am now working for that previous customer and reviewed the code that I was missing.

On Page 280 of my book, there is Listing 18.5. You'll see the "Get the Changes" line which calls the Diff method of the SPDiffUtility. Before this line, enter the following:

oldValue = oldValue.Replace("\n", SPDiffUtility.ChangeOpenTag + "<br></br>" + SPDiffUtility.ChangeCloseTag);
newValue = newValue.Replace("\n", SPDiffUtility.ChangeOpenTag + "<br></br>" + SPDiffUtility.ChangeCloseTag);


You'll need to declare oldValue and newValue prior to these lines. You can set these to the event values e.OldValue and e.NewValue. Without using these replace statements, any line breaks in the original text do not get reflected in the track changes text. Replacing the line breaks (\n) with the html shown above preserves the new lines in the tracked changes.


If you found this useful, please help support my SharePoint and .NET user group (Philly SNUG) by clicking on the logo below.

Tuesday, January 18, 2011

SharePoint 2010: Removing GUIDs in Several Service Application Database Names

Introduction

I noticed a few months ago that Shane Young was on a mission to explain how to remove the GUID from the default database names that are generated for each service application in SharePoint 2010. His main post which contains links to specific items is available here.

I luckily ran into several service applications that make it easy to rename the database as a new database is created and configured.

Word Automation Services
This was the first one I found. Using the SharePoint Powershell cmdlet, Set-SPWordConversionServiceApplication allows you to create a new database:

Set-SPWordConversionServiceApplication -Identity "Word Automation Services" -DatabaseServer SP2010\SQLSharePoint -DatabaseName WordServices

Managed Metadata Service
The Managed Metadata Service works the same way:

Set-SPMetadataServiceApplication –Identity “Managed Metadata Service” –DatabaseName TermStoreDB


Business Data Connectivity Service
The BCS works similiar:

$bcs = Get-SPServiceApplication -Identity bc4399ed-a2e0-4397-bf07-cd3d207e630e
Set-SPBusinessDataCatalogServiceApplication –Identity $bcs –DatabaseName BCS_DB

NOTE: You can find the GUID by using Get-SPServiceApplication and finding the BCS Service in the listing.

 

Secure Store Service
The Secure Store Service is similiar yet different. The Set-SPSecureStoreServiceApplication needs the identity of the service application, so you need to get that first:

$sss = Get-SPServiceApplication -Identity bc4399ed-a2e0-4397-bf07-cd3d207e630e
Set-SPSecureStoreServiceApplication –Identity $sss –DatabaseName SecureStoreDB

NOTE: You can find the GUID by using Get-SPServiceApplication and finding the Secure Store Service in the listing.

Here's the tricky part, although the command lines above run and take a few moments to process, the new database is not created. The new database name is set within the properties but SQL Server knows of no such thing. The easy fix here is to view the Secure Store Service Application properties from within Central Admin and click OK. Even though you may not have changed anything from the UI, the database name will be processed and a new database will be created.



Since you need to visit Central Admin anyway, you may just want to skip the PowerShell part and go right into the properties to change the name there.


Conclusion
Each service application has its own way of doing things, however, some make it easy to change the database name and actually create a new instance in SQL Server. Once the new databases are created, you can drop the old databases with the GUID. You may need to restart your servers such that the old databases are no longer in use. If you found this useful, please help support my SharePoint and .NET user group (Philly SNUG) by clicking on the logo below.

Saturday, December 4, 2010

SharePoint 2010: Using Visual Studio 2010 to Create a List Definition and List Instance (Based on a new Content Type)

In order to programmatically add a new list definition and instance based on a new content type, you will need to expand upon the solution/project created in the content type post. Right-click the project and select Add New Item. The Add New Item dialog appears:

Select List Definition from Content Type, enter a name, and then click Add. The SharePoint Customization Wizard appears:


Enter an appropriate display name for the list definition and select the content type from the drop-down. The drop-down will only show the content types that are being defined within the current solution. Leave the Add a list instance checked if you want the deployment of the solution to create the actual list. Click Finish.
The list definition elements file is opened. Add Unique=”TRUE”. The Unique setting means that the list instance will be created once and there is no need to show this definition to the users moving forward:

Expand the ListInstance1 item in the Solution Explorer and click on the Elements.xml underneath. This defines the instance of the list (or document library). Change the title to determine the name of the list instance. If the list will be a document library, modify the URL setting by removing the “Lists/”. Enter a name without spaces for the URL. Enter an appropriate description:

Save all of the changes to the files.

Right-click the Project in Solution Explorer and select Deploy. The content type package is built and added to the SharePoint farm solutions. The solution is deployed globally as a feature that is available at the site level. The site feature will be activated at the root site collection but may not be activated within other sites. The site columns, content type, and list (document library) are created accordingly on the root site.


If you found this useful, please help support my SharePoint and .NET user group (Philly SNUG) by clicking on the logo below.

Matched Content