It has been quite awhile since I had presented at a user group or event!  I think the presentation went very well, had plenty of material and I think plenty of demos to help give attendees an idea of what's possible with SharePoint 2013 Search.  I'd like to expand on this presentation and present it again hopefully at another event.  Ideally I'd like to add some demos about using Knockout and AngularJS.


http://www.spsevents.org/city/Philadelphia/Philly2014/home

Presentation Link : Code/Slides

 


 

This past weekend I presented at the SharePoint Satuday event in Philly.  It was another great SharePiont Saturday with over 400+ people showing up to the event.

I presented on setting up a Continuous Integration process with SharePoint.  I think overall the session went well, demo's went off smoothly and there were a lot of good audience questions which sparked some good conversations.

 

http://www.sharepointsaturday.org/philly/default.aspx 

 

Presentation Link : Code/Slides

 


Here was my problem; I had a SharePoint site which served as a companies intranet and thus had quite a few sub sites and therefore the top navigation bar had quite a few tabs.  Obviously this isn’t an the wall scenario and I’m sure that most people can relate if they’ve seen a company use SharePoint as their main intranet.  The issue was the number of tabs that they had on their top navigation caused the browser, even on LARGE monitors, to have horizontal scroll bar.  This wasn’t cutting it for the client and they needed a solution to wrap the tabs so that their would be multiple lines of intranet site tabs.

I wasn’t originally the developer assigned to this task.  The original developer took the typical approach and looked around to see if we this problem had been previously solved.  The telerik asp.net controls were identified as a solution since it had a navigation control that looked promising.  I was told that this control would automatically wrap the tabs.  Of course…when I was put on the project and tried out the telerik control…i didn’t wrap and I started to shit myself since I was only given a short timeframe to complete the task since the control was SUPPOSED to work.  After I played around a bit as well, I noticed that the telerik navigation control really didn’t style itself well with SharePoint, it looked out of place, even with its “office” theme.

My initial custom approach I thought would be pretty simple, so I added a content editor webpart to the page and began dusting off my javascript skills and trying to edit the DOM.  After about a day, I was ready to pull my hair out for 2 reasons, first being that I couldn’t solve it, and the second was that javascript just flat out blows if you aren’t doing it 5 days a week.  The basic javascript approach was something that I though would work best since all it needed was a content editor webpart and pasting in some code, I could then add that code to the master page.

Being that I had recently learned to love jQuery, I gave that a shot but frankly I am just not that well versed with jQuery to accomplish what I needed, in addition I would have to include jQuery into the master page and thus slow down the render of each page (which was already a complaint of the client).

After roaming the net I stumbled across a little known ASP.NET “browser” file which basically allows you to tell the asp.net web application that for any control that is using X class, pass it through to your adapter class, through the use of control adapters.  All you need is the class you want to inject, and the browser file which tells asp.net to do the replacement.

Here is what the browser file looks like:

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter controlType="Microsoft.SharePoint.WebControls.AspMenu, Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"
      adapterType="DTCubed.Navigation.MenuAdapter" />
    </controlAdapters>
  </browser>
</browsers>

 

As you can see I am telling my web application that for the AspMenu control, from the SharePoint.WebControls namespace, replace it with my custom MenuAdapter.

The code for my MenuAdapter class is pretty simple:

namespace DTCubed.Navigation
{
    public class MenuAdapter : ControlAdapter
    {
        private string MAX_TAB_COUNT = ConfigurationManager.AppSettings["MaxTabCountPerLine"].ToString();
 
        protected override void Render(System.Web.UI.HtmlTextWriter writer)
        {
            StringBuilder sb = new StringBuilder();
            StringWriter stringWriter = new StringWriter(sb);
 
            HtmlTextWriter htmlWriter = new HtmlTextWriter(stringWriter);
            base.Render(htmlWriter);
 
            string txt = sb.ToString();
            txt = txt.Replace("<td style=\"width:0px;\"></td>","");
            string txtToFind = "<td onmouseover=\"Menu_HoverStatic(this)\" onmouseout=\"Menu_Unhover(this)\" onkeyup=\"Menu_Key(this)\" id=\"zz1_TopNavigationMenun";
            bool stringFound = true;
 
            int txtFoundIdx = 0;            
            int currentTabCount = 0;
            int currentTabIdx = 0;
            int tabCount = 0;
 
            //check the tab count config setting, if it exists, set our variable, if not, default it.
            if(string.IsNullOrEmpty(MAX_TAB_COUNT))
                tabCount = 12;
            else
                tabCount = Int32.Parse(MAX_TAB_COUNT);
 
            while (stringFound)
            {
                stringFound = false;
 
                txtFoundIdx = txt.IndexOf(txtToFind, currentTabIdx);
 
                if (txtFoundIdx > 0)
                {
                    stringFound = true;
                    currentTabCount++;
                    currentTabIdx = txtFoundIdx + 10;
 
                    if (currentTabCount == tabCount)
                    {
                        currentTabCount = 0;
                        txt = txt.Insert(txtFoundIdx, "</tr><tr>");
                    }
                }
            }
            writer.Write(txt);
        }
 
    }
}

What is going on here is that I am inheriting from the ControlAdapter class and making my own class where I can modify the Render method, basically modifying the output of the AspMenu class.  As you can see in the Render method, I am taking the HTML output of the AspMenu class, searching it, and breaking it after X number of tabs.  I also have it reading from the Web.Config to tell how many tabs to break at so that you can easily change it to meet your needs.

All that is needed to deploy this is to deploy the DLL to the GAC (or the BIN), put the .browser file into the “App_Browser” directory, add the web.config app key for tab count, and do an IIS reset.  The beauty of this is that it will work on any site collection underneath the web application and there are no modifications needed to the sites themselves or master pages.

Below is the zipped up code…technically its packaged as a feature, but the feature doesn’t actually deploy cleanly (I am working on fixing that at the moment). 

DTCubed.Navigation.zip (429.90 kb)


Sorry it took me so long but I've finally had a chance to post my code and slides from this past Philly.Net Code Camp.  Thanks for all that attended, hopefully I showed everyone in the audience how easy it is to integrate AJAX, jQuery and Silverlight.

If anyone has any follow up questions, please let me know and I will gladly help out where I can. 

 

Here are the goods:  PhillyDotNet_Code Camp_Moss_Ajax_jQuery_Silverlight.zip


Here are the code and slides from my march presentation at Philly Office Geeks title "MS AJAX and jQuery with SharePoint"

 

20090310_OfficeGeeks_TonyTesta_AJAX_JQuery.zip


Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2017 Tony Testa's World