Foros‎ > ‎Sharepoint‎ > ‎

SharePoint: Overcome the Top Navigation bar issue with Touch Devices, Phones - Mobile

publicado a la‎(s)‎ 8 abr. 2015 13:42 por Ignacio Gonzalez

 SharePoint: Overcome the Top Navigation bar issue with Touch Devices, Phones ... etc

Ever wondered once you have deployed your Portal on an Environment, how would it look like when using touch tablets (iPad, Windows 8 Tablets, Android Tablets...etc) ?

Well, one of the main issues that I faced was the Top Navigation Bar Hovering Sub-Menus.

By design, SharePoint OOB Top Navigation Menu works as follows (dah !!):
1- You hover you mouse on the Parent Menu
2- While hovering, you can see the Sub-Menu Items Drop down
3- By a Mouse Click, You choose the sub-menu you want, to be redirected to the desired URL

But when using a touch devices, once you point your finger on the parent menu, you are redirected to your destination directly, without even the chance to see the sub-menu items dropdown (Damn!!! :D)

So, a couple of searches on the internet, and I was able to inject a JQuery Script in my master-page to avoid this, and at the same time, it works as expected with normal PCs (mouse hovering and such)

So here you go:

First: Add a reference to JQuery (I'm using Google's API):

<script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.0/jquery.min.js"></script>

Then Start Writing the following Script (covering almost all devices I can find/think of):

<script>
//Ahmed Medhat: Upadting SharePoint OOB Hovering for iPad/iDevices/Windows-RT
jQuery(document).ready(function() {    
if((navigator.userAgent.match(/iPhone/i)) || 
(navigator.userAgent.match(/iPod/i)) || 
(navigator.userAgent.match(/iPad/i)) || 
(navigator.userAgent.match(/Android/i)) ||
(navigator.userAgent.match(/blackberry/i)) || 
(navigator.userAgent.match(/1000/i)) || 
(navigator.userAgent.match(/9000/i)) || 
(navigator.userAgent.match(/m180/i)) || 
(navigator.userAgent.match(/t849/i)) || 
(navigator.userAgent.match(/i987/i)) || 
(navigator.userAgent.match(/tablet/i)) || 
(navigator.userAgent.match(/p100/i)) ||
(navigator.userAgent.match(/i800/i)) ||
navigator.userAgent == "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.2; ARM; Trident/6.0; Touch; .NET4.0E; .NET4.0C; Tablet PC 2.0)" ||
navigator.userAgent == "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0; Touch; .NET4.0E; .NET4.0C; Tablet PC 2.0)")
{
jQuery("a.dynamic-children").click(function(e) {
  if($(this).attr('select') == null)
  {
$(this).attr('select','true');
if(e.preventDefault){
        e.preventDefault();
    }
else{
//e.stopImmediatePropagation();
//e.returnValue = false;
//e.cancelBubble=true;
setTimeout(function(){},3000);
}
  }
  else if ($(this).attr('select') == 'true')
  {
$(this).removeAttr('select');
  var location = $(this).attr("href");
    window.location = location;
  }
});

jQuery("a.dynamic-children").mouseout(function() {
  $(this).removeAttr('select');
});

}});

</script>

To properly, understand the Script, let me take it step by step:

1- Checking the Current User Agent (Device Accessing the Portal):


<script>
//Ahmed Medhat: Upadting SharePoint OOB Hovering for iPad/iDevices/Windows-RT
jQuery(document).ready(function() {    
if((navigator.userAgent.match(/iPhone/i)) || 
(navigator.userAgent.match(/iPod/i)) || 
(navigator.userAgent.match(/iPad/i)) || 
(navigator.userAgent.match(/Android/i)) ||
(navigator.userAgent.match(/blackberry/i)) || 
(navigator.userAgent.match(/1000/i)) || 
(navigator.userAgent.match(/9000/i)) || 
(navigator.userAgent.match(/m180/i)) || 
(navigator.userAgent.match(/t849/i)) || 
(navigator.userAgent.match(/i987/i)) || 
(navigator.userAgent.match(/tablet/i)) || 
(navigator.userAgent.match(/p100/i)) ||
(navigator.userAgent.match(/i800/i)) ||
navigator.userAgent == "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.2; ARM; Trident/6.0; Touch; .NET4.0E; .NET4.0C; Tablet PC 2.0)" ||
navigator.userAgent == "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0; Touch; .NET4.0E; .NET4.0C; Tablet PC 2.0)")

As you can see, I'm just checking if the user agent matches any of the above devices, such as "iPhone/i" or "iPad/i" which is the agent's name.
As for Windows Surface or Other Windows Tablet Devices, you'll need to match with that user  agent name "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; ARM; Trident/6.0; Touch; .NET4.0E; .NET4.0C; Tablet PC 2.0)".
but be careful to change the compatibility version of the IE you specified in your masterpage (I added IE 8 & 10 for an example)

Once the code detects that you are using one of these browsers, then you can get the current pressed menu item by referring its href class "dynamic-children" using jQuery

jQuery("a.dynamic-children").click(function(e) {


2- Checking if the current pressed parent menu has an attribute called "select" (which of course there isn't):

if($(this).attr('select') == null)

if not, then add the select attribute to that parent menu

$(this).attr('select','true');

After adding this attribute, I need to prevent the default action of the menu item from redirecting you to its specified URL

if(e.preventDefault){ //Works only with other browsers than IE :(
         e.preventDefault();
     }

The above action works only with browsers other than IE, so to overcome that using an IE browser, I just thought to add a three seconds halt for the menu item before it redirects the user to its destination URL

else{
//e.stopImmediatePropagation(); //Didn't Work :(
//e.returnValue = false; //Didn't Work, although lot of articles said it would
//e.cancelBubble=true; //Didn't Work :(
setTimeout(function(){},3000); //My Solution :D
}

3- Now, Check if the User already pressed on the parent menu item and decides once again to press on it to go to planned destination URL

else if ($(this).attr('select') == 'true')
  {
$(this).removeAttr('select');
  var location = $(this).attr("href");
    window.location = location; //Simulating the normal redirection behavior of the parent menu
  }

4- Finally, When the User has a menu item already opened, and decides to click on another parent menu item, so we need to switch the "select" attribute from the old parent menu to the new pressed parent menu item. So simply remove the "select" attribute from the old parent menu and when the user presses on a new parent menu, it will start over through the code and check if that menu item has the "select" attribute or not (check step 1).

jQuery("a.dynamic-children").mouseout(function() {
  $(this).removeAttr('select');
});

And Voila !!!!

For the IE browser part, I know it not the best solution, but its the most acceptable solution I found till now, maybe someone could provide something better ;)


Note: If you need to use as well touch phones and experience the portal in that design not in default SharePoint mobile redirect view, then:

  • Add the below segment to the "configuration/system.web" section of your web application's web.config
  • The segment to add:
    • <browserCaps><result type=”System.Web.Mobile.MobileCapabilities, System.Web.Mobile, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”/><filter>isMobileDevice=false</filter></browserCaps>
Comments