Wednesday, March 9, 2011

Sharepoint Branding With CSS and Javascript Part 3

So here we are in part 3 of my series of posts on creating a CSS based site in WSS. In my first two posts, I went over the master page and the stylesheets used in this solution. In this post, I am going to go over the xml menus and the javascript coding that makes the rest of it all stick together. I will break this into a few sections.

Keep in mind that my solution is just that! It is a Visual Studio 2008 solution for a site definition. As I said earlier though, you do not have to do it this way. With that in mind, to duplicate what I have, you need to at least have the following things done:

  • An images folder in the Master Page Gallery. (It is just a doc library!)
  • The stylesheets you want to use loaded into the Master Page Gallery. (I used 5)
  • A doc library called Scripts in the root of the site.
For the two navigation areas, I used xml files that I placed in the script library mentioned above. This makes changing the menus rather easy. Here is my code for these menus starting with the mainmenu:

  1. <ul>
  2.     <li><a class="hide" href="javascript:loadpage('/default.aspx');">Home</a></li>
  3.     <li><a class="hide" href="javascript:loadpage('/Lists/Tracking/AllItems.aspx');">Tracking</a>
  4.     <ul>
  5.       <li><a href="javascript:loadpage('/Lists/Tracking/Project.aspx');">By Project</a></li>
  6.       <li><a href="javascript:loadpage('/Lists/Tracking/Code.aspx');">By Code</a></li>
  7.       <li><a href="javascript:loadpage('/Lists/Tracking/Engineer.aspx');">By Engineer</a></li>
  8.       <li><a href="javascript:loadpage('/Lists/Tracking/Supervisor.aspx');">By Supervisor</a></li>
  9.       <li><a href="javascript:loadpage('/Lists/Tracking/Reference.aspx');">By Reference</a></li>
  10.       <li><a href="javascript:loadpage('/Lists/Tracking/MyItems.aspx');">My Items</a></li>
  11.     </ul>
  12.   </li>
  13.     <li><a class="hide" href="javascript:loadpage('/Lists/Twds/AllItems.aspx');">Twds</a>
  14.     <ul>
  15.       <li><a href="javascript:loadpage('/Lists/Twds/Project.aspx');">By Project</a></li>
  16.       <li><a href="javascript:loadpage('/Lists/Twds/Code.aspx');">By Code</a></li>
  17.       <li><a href="javascript:loadpage('/Lists/Twds/Engineer.aspx');">By Engineer</a></li>
  18.       <li><a href="javascript:loadpage('/Lists/Twds/Supervisor.aspx');">By Supervisor</a></li>
  19.       <li><a href="javascript:loadpage('/Lists/Twds/Reference.aspx');">By Reference</a></li>
  20.       <li><a href="javascript:loadpage('/Lists/Twds/MyItems.aspx');">My Items</a></li>
  21.     </ul>
  22.   </li>
  23.     <li><a class="hide" href="javascript:loadpage('/Lists/References/AllItems.aspx');">References</a></li>
  24.     <li><a class="hide" href="mailto:evilgenius@fake.net">Contact</a></li>

Yes, it is not complete and there is a cool reason for this. If you look back at the code for the master page, I left the site actions control there but in a hidden div element. Part of the script will use some code to get the href elements of the hidden site settings and add it to the main navigation at the end. I think that is slick don't you!

Here is the code for the side menu:

  1. <div class="sidebarbutton">Tracking</div>
  2.     <div class="sidebarcontent" id="sidebarcontent">
  3.         <ul>
  4.           <li><a href="javascript:loadpage('/Lists/Tracking/Project.aspx');">By Project</a></li>
  5.           <li><a href="javascript:loadpage('/Lists/Tracking/Code.aspx');">By Code</a></li>
  6.           <li><a href="javascript:loadpage('/Lists/Tracking/Engineer.aspx');">By Engineer</a></li>
  7.           <li><a href="javascript:loadpage('/Lists/Tracking/Supervisor.aspx');">By Supervisor</a></li>
  8.           <li><a href="javascript:loadpage('/Lists/Tracking/Reference.aspx');">By Reference</a></li>
  9.           <li><a href="javascript:loadpage('/Lists/Tracking/MyItems.aspx');">My Items</a></li>
  10.         </ul>
  11.     </div>
  12. <div class="sidebarbutton">Twds</div>
  13.     <div class="sidebarcontent" id="sidebarcontent">
  14.         <ul>
  15.           <li><a href="javascript:loadpage('/Lists/Twds/Project.aspx');">By Project</a></li>
  16.           <li><a href="javascript:loadpage('/Lists/Twds/Code.aspx');">By Code</a></li>
  17.           <li><a href="javascript:loadpage('/Lists/Twds/Engineer.aspx');">By Engineer</a></li>
  18.           <li><a href="javascript:loadpage('/Lists/Twds/Supervisor.aspx');">By Supervisor</a></li>
  19.           <li><a href="javascript:loadpage('/Lists/Twds/Reference.aspx');">By Reference</a></li>
  20.           <li><a href="javascript:loadpage('/Lists/Twds/MyItems.aspx');">My Items</a></li>
  21.         </ul>
  22.     </div>
  23. <div class="sidebarbutton">Information</div>
  24. <div class="sidebarcontent" id="sidebarcontent">
  25.   <table width="100%">
  26.     <tr>
  27.       <td>Title:</td>
  28.       <td>Totally Fake Title!</td>
  29.     </tr>
  30.     <tr>
  31.       <td>Designed By:</td>
  32.       <td>A wickedly cool guy!</td>
  33.     </tr>
  34.     <tr>
  35.       <td>Functional POC:</td>
  36.       <td>
  37.         <a href="mailto:evilgenius@fake.net">Evil Genius (At cox.net)</a>
  38.       </td>
  39.     </tr>
  40.     <tr>
  41.       <td>Technical POC:</td>
  42.       <td>
  43.         That same cool guy.
  44.       </td>
  45.     </tr>
  46.   </table>
  47. </div>

This is the code for the accordion style menu on the right. It is neat and again can be changed as needed. The stylesheets handle the formatting for this.

Now let's go over the javascript code!

  1. var source;
  2. var test = null;
  3. var loc = null;
  4. var viewpage = null;
  5. var viewname;
  6. var reqXML;
  7. var menuhtml;
  8. $(document).ready(function() {
  9.     source = window.location;
  10.     test = new String(window.location);
  11.     /* ---------------------------------------- Begin Menu Section ------------------------------------------------------------*/
  12.     // Get and load the menu data
  13.     lnk = L_Menu_BaseUrl + "/Scripts/mainmenu.xml";
  14.     req = new ActiveXObject("Microsoft.XMLHTTP");
  15.     if (req) {
  16.         req.open("GET", lnk, false);
  17.         req.send();
  18.         menuhtml = req.responseText;
  19.     }
  20.     // Can we add site settings links to the menu?
  21.     menuhtml += "<li><a class='hide' href='#'>Site Settings</a>";
  22.     menuhtml += "<ul>";
  23.     $("menu[id*='FeatureMenuTemplate1'] ie\\:menuitem").each(function() {
  24.         menuhtml += "<li><a href=\"javascript:" + $(this).attr('onMenuClick') + "\"; >" + $(this).attr('text') + "</a></li>";
  25.     });
  26.     menuhtml += "</ul></ul>";
  27.     $("#menu").html(menuhtml);
  28.     lnk2 = L_Menu_BaseUrl + "/Scripts/sidemenu.xml";
  29.     req2 = new ActiveXObject("Microsoft.XMLHTTP");
  30.     if (req2) {
  31.         req2.open("GET", lnk2, false);
  32.         req2.send();
  33.         $("#sidemenu").html(req2.responseText);
  34.     }
  35.     $('.sidebarbutton').click(function() {
  36.         $('.sidebarcontent').slideUp('normal');
  37.         if($(this).next().is(':hidden') == true) {
  38.             $(this).next().slideDown('normal');
  39.         }
  40.     });
  41.     $('.sidebarbutton').mouseover(function() {
  42.         $('.sidebarcontent').slideUp('normal');
  43.         if ($(this).next().is(':hidden') == true) {
  44.             $(this).next().slideDown('normal');
  45.         }
  46.     });
  47.     $(".sidebarcontent").hide();
  48.     /*------------------------------------------ End Menu Section -------------------------------------------------------------*/
  49.     /*----------------------------------------- Begin Style Section -----------------------------------------------------------*/
  50.     // Can we determine our useable resolution?
  51.     var h = screen.availHeight;
  52.     var w = screen.availWidth;
  53.     h = h - 350;
  54.    
  55.     // load a stylesheet based on the resolution
  56.     if (w < 1024) {
  57.         switchstyle("default");
  58.     }
  59.     if (w >= 1024 && w < 1280) {
  60.         switchstyle("mcurves1024");
  61.     }
  62.     if (w >= 1200 && w < 1440) {
  63.         switchstyle("mcurves1200");
  64.     }
  65.     if (w >= 1440 && w < 1600) {
  66.         switchstyle("mcurves1440");
  67.     }
  68.     if (w >= 1600) {
  69.         switchstyle("mcurves1600");
  70.     }
  71.     /*------------------------------------------ End Style Section ------------------------------------------------------------*/
  72.     viewname = "";
  73.     viewname = $("td[id*='onetViewSelector']").text();
  74.     if (viewname == "") { viewname = "All"; }
  75.     try {
  76.         var $table = $("TABLE[Summary*='MCurveData']");
  77.         $table.wrap("<div id='wptable1' style='height:" + h + "px;overflow:scroll;'></div>");
  78.         $("TR.ms-viewheadertr:first", $table).addClass("fixedheader");
  79.     }
  80.     catch (e) { }
  81.     $("#printalert").dialog({
  82.         bgiframe: true,
  83.         autoOpen: false,
  84.         resizable: false,
  85.         modal: true,
  86.         position: ['center', 'center'],
  87.         overlay: { backgroundColor: '#ffdddd', opacity: 0.8 },
  88.         height: 150,
  89.         width: 475,
  90.         closeOnEscape: true,
  91.         title: 'ALERT',
  92.         buttons: { "OK": function() { $(this).dialog("close"); } }
  93.     });
  94.     window.onbeforeprint = function() { beforeprint(); }
  95. });
  96. function switchstyle(style) {
  97.     var z, tag;
  98.     for (z=0, tag = document.getElementsByTagName("link"); z < tag.length; z++)
  99.     {
  100.         if ((tag[z].rel.indexOf("stylesheet") != -1) && tag[z].title)
  101.         {
  102.             tag[z].disabled = true;
  103.             if (tag[z].title == style)
  104.             {
  105.                 tag[z].disabled = false;
  106.             }
  107.         }
  108.     }
  109. }
  110. function sitesettings() {
  111.     var smenua = $("menu[id*='FeatureMenuTemplate1']").attr("id");
  112.     var smenub = $("a[id*='SiteActionsMenu']").attr("id");
  113.     MMU_Open(byid(smenua), MMU_GetMenuFromClientId(smenub), event, false, null, 0);
  114. }
  115. function SearchIt() {
  116.     var k = $("#search-text").val();
  117.     var lnk = L_Menu_BaseUrl + "/_layouts/searchresults.aspx?k=" + k;
  118.     window.location = lnk;
  119. }
  120. function loadpage(lnk) {
  121.     lnk = L_Menu_BaseUrl + lnk;
  122.     window.location = lnk;
  123. }
  124. function beforeprint() {
  125.     $("#printalert").dialog("open");
  126. }

So there you have the code! As you can see I show how I add the site settings links to the main menu and then I load the accordion menu and setup the "buttons" to allow the accordion functionality to work. This could be modified to just a click event if desired. The next thing that I do here is check the width of the screen to determine which of the loaded stylesheets should be set as active. Remember that I load all of them in the master page. This just determines which one to set.

There are some other things here that I use to make things look better. In list view pages, I try to keep the list views from scrolling off the page to ensure that the footer is always at the bottom and that items do not scroll under it. You will find a try/catch block here that wraps the list view in a scrollable div and also sets the header row to fixed so that it functions similar to locked rows in Excel. This function was for a specific listview and should be changed or removed. I did not take the time to set a fixed height for the content div so I just used some math to sort of guess how tall it should be.

The other function of note that I left in here is the sitesettings function. If you wanted to create a button or some other method to run it, the function opens the real site actions where it is so in my case I chose not to add this.

The styles that I used are carried maybe a bit too far as the toolbar dropdowns are black with red hover like the main menu, but I wanted to show that you could do it and I kind of like it!

Well, that is it for this series of posts! I would really like your comments and feedback!

1 comment:

  1. i read it very interesting.
    do you have this wsp i can deploy?
    i will be very interesting in that.

    ReplyDelete