Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • Paul Griffiths 370 posts 1021 karma points
    Jan 15, 2015 @ 11:04
    Paul Griffiths
    0

    Displaying Hidden Nav items on Mobile

    Hello everyone,

    I think this issue is xslt related and hoping someone can help me figure out a solution for it please. I have built a little website for a friend and i am struggling to display navigation items that i have chosen to hide from the main nav (umbracoNaviHide) when viewing it in a mobile.

    The website is still being worked on but can be viewed here http://valentinetravel.co.uk/ so you can see the issue that i am experiencing (resize your browser to mobile size). When viewing all pages that are shown in the main navigation the mobile nav works fine (see below)

    The Nav Working - Selecting the current page

    but when viewing one of the pages which is not a main nav item (umbracoNaviHide) the nav breaks which i think is becuase of the logic and the class i am applying in the xslt.

    The Nav not working - Not selecting the current page

    The pages that are hidden from the main nav are News, Privacy Policy, Sitemap, T&C'S so when viewing these i am unable to show the current page in the nav.

    Here is the xslt code that i have to display the Nav items

        <xsl:output method="xml" omit-xml-declaration="yes"/>
    
    <xsl:param name="currentPage"/>
    <xsl:variable name="level" select="1"/>
    <xsl:template match="/">
    
    <!-- start writing XSLT -->
        <nav>
        <!--<h2 class="hidden">Main Navigation</h2>-->
        <ul>
            <li>
                    <xsl:if test="$currentPage/@id = $currentPage/ancestor-or-self::* [@level=$level]/@id">
                        <xsl:attribute name="class">current</xsl:attribute>
                    </xsl:if>
                <a title="home" href="/">
                    <xsl:if test="$currentPage/@id = $currentPage/ancestor-or-self::* [@level=$level]/@id">
                        <xsl:attribute name="class">selected</xsl:attribute>
                    </xsl:if>
                    <span>home</span>
                </a>
            </li>
            <xsl:variable name="topNode" select="$currentPage/ancestor-or-self::*[@level = $level]" />
            <xsl:for-each select="$topNode/*[@isDoc][not(umbracoNaviHide = 1)]">
                <li>
                    <xsl:if test="@id = $currentPage/ancestor-or-self::*/@id">
                            <xsl:attribute name="class">current</xsl:attribute>
                     </xsl:if>              
                    <xsl:if test="position() = last() and @id = $currentPage/ancestor-or-self::*/@id">
                        <xsl:attribute name="class">last current</xsl:attribute>
                    </xsl:if>
                    <a href="{umbraco.library:NiceUrl(@id)}">
                        <xsl:if test="@id = $currentPage/ancestor-or-self::*/@id">
                            <xsl:attribute name="class">selected</xsl:attribute>
                        </xsl:if>
                        <span><xsl:value-of select="@nodeName"/></span>
                    </a>
                </li>
            </xsl:for-each>
        </ul>
    </nav>
    
    
    </xsl:template>
    
    </xsl:stylesheet>
    

    and here is my css for the navigation for when the website is being viewed on small devices such as mobile

    /*Nav Amends */
    nav {position: relative; min-height: 40px;  }   
    nav ul {margin: 0; padding: 0; width: 160px; padding: 5px 0; position: absolute; top: 4px; left: 0; border: solid 1px #aaa; background: #fff url(/images/media/icon-menu.png) no-repeat 10px 11px;  box-shadow: 0 1px 2px rgba(0,0,0,.3); height:auto; overflow:auto;}
    /* hide all <li> items */
    nav ul li {display: none;  margin: 0; padding:0; float:none; background:none;}
    nav ul li.current {color:#C0902E; display: block; /* show only current <li> item */}
    nav ul li a {color:#01184A; display: block; padding: 3px 5px 5px 32px; text-align: left; line-height:100%; text-align:initial; text-decoration:none; width:auto; background:none; }
    nav ul li a span {background:none !important; height:auto;}
    nav ul li.current a {background: none; color: #C0902E;}
        /* on nav hover */
    nav ul:hover {background-image: none; border-bottom-left-radius:5px; border-bottom-right-radius:5px;}
    nav ul:hover li {display: block; margin: 0 0 5px;}
    nav ul li a:hover {color:#C0902E;}
    nav ul li a span {background:none;}
    nav ul:hover .current {background: url(/images/media/icon-check.png) no-repeat 10px 7px;}
    

    If you need me to explain anything else please dont hesitate to get in touch. Ive really enjoyed working on this little project but this issue has got me :(

    Many Thanks

    Paul

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Jan 15, 2015 @ 11:27
    Jan Skovgaard
    0

    Hi Paul

    It has nothing to do with your XSLT file. It is related purely to CSS. It's because you have display:none on your li when styling it on the mobile breakpoint

    Search for media="screen and (max-width: 568px) and (min-width: 320px) and then look for

    nav ul li{
    display: none;
    margin: 0;
    padding: 0;
    float: none;
    background: none;
    }
    

    If you remove "display: none" from the above rule then it shows fine on the news page.

    Hope this helps.

    /Jan

  • Paul Griffiths 370 posts 1021 karma points
    Jan 15, 2015 @ 11:49
    Paul Griffiths
    0

    Hi Jan,

    Thanks for you quick response.

    I have had just tried what you suggested but i had no luck (unless i did something wrong?). Have you been able to debug and get it working?

    Before i wrote the post my thinking behind this (which may be completely wrong) was i have written my xslt so that it never displays pages that are checked with umbracoNaviHide in the main navigation so regardless of what styles that i apply the news page is never displayed in the nav because i have decided to hide it - This means that the .current class to display any page that is checked to not be shown in the main nav will not be applied and therfore when the user is on a page that is not a main nav item it will not be shown.

    <xsl:for-each select="$topNode/*[@isDoc][not(umbracoNaviHide = 1)]">
        <li>
            <xsl:if test="@id = $currentPage/ancestor-or-self::*/@id">
                    <xsl:attribute name="class">current</xsl:attribute>
             </xsl:if>  
    

    Hope this makes sense - I have been looking at this for way to long and may be overthinking

    Many thanks

    Paul

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Jan 15, 2015 @ 11:57
    Jan Skovgaard
    0

    Hi Paul

    Since it does not seem like you rely on any device detection service like wurl or 51degrees it can't be the XSLT file since that would also hide those nodes from the desktop viewing then.

    All you do is change the way the site is represented depending on the screen real estate.

    What I did before was the following

    1: Emulate an iPhone device using the chrome dev tools 2: Go to the "News" page 3: Inspect the weird looking main navigation 4: Noticed that the pages are rendered in the li element by using the inspector tool in chrome 5: Had a look at the styling for the li elements and noticed that at the breakpoint mentioned above it said "display:none".

    It seems you have a general rule that is saying that all li items nested under ul nested under nav should be hidden. So perhaps you have some other navigation that you intend to hide but it might be a good idea to add a class name to the different

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Jan 15, 2015 @ 12:01
    Jan Skovgaard
    0

    Hi Paul

    Sorry, forget all about what I wrote above in my two previous posts! I'm wrong...it's because the "current" class is missing when rendering the navigation on the "news" page.

    High 5 I suck!

    I'll go over you XSLT examples again when I've had some lunch unless someone else beats me to it.

    /Jan

  • Paul Griffiths 370 posts 1021 karma points
    Jan 15, 2015 @ 12:18
    Paul Griffiths
    0

    Hi Jan,

    No worries mate thanks for looking, Thats what i was trying to say in my above post but think i didnt explain it very well. I think i need some logic to say if the current page is not a main nav item then display it in the nav. I think you can apply the current class too.

    Cheers

    Paul

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Jan 15, 2015 @ 12:27
    Jan Skovgaard
    0

    Hi Paul

    Yeah, I'm a bit puzzled as to why the "current" class is not set when you're at a page that does not render in the main menu since all you say is that you want to display all topnodes, that are not hidden and that's also what happens. The nodes are rendering just fine but the class is just not set.

    Could you try changing this

            <xsl:if test="@id = $currentPage/ancestor-or-self::*/@id">
                    <xsl:attribute name="class">current</xsl:attribute>
             </xsl:if>
    

    to this

            <xsl:if test="@id = current()/@id">
                    <xsl:attribute name="class">current</xsl:attribute>
             </xsl:if> 
    

    Unfortunately I'm a bit rusty - It's been a while since I have written XSLT :-/ So no guarantees it will work.

    /Jan

  • Paul Griffiths 370 posts 1021 karma points
    Jan 15, 2015 @ 12:46
    Paul Griffiths
    0

    Hi Jan,

    Thanks for looking into this, Ill be honest im very much a newb with xslt and just manage to get by at the moment but from my understanding the .current class is not being applied to any page that has a value equal to umbracoNaviHide=1 because of this line here

    we are basically saying only list any page that is not equal to umbracoNaviHide = 1 (Home, About us Our services etc..) and then once we have listed each page then apply the the current li item with an attribute of class .current. Because we are never listing out pages that are equal to umbracoNaviHide = 1 then they wont appear in the navigation regardless if the .current class is applied or not.

    This is why i thought i needed to extend my xslt somehow?

    Thats my understand and Hope that makes sense?

    Ps i tried your solution but no luck sorry.

    Thanks again

    Paul

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Jan 15, 2015 @ 13:03
    Jan Skovgaard
    0

    Hi Paul

    In short your top menu is rendering fine. That culprit is why the "current" class is not set when visiting a page that is hidden from the navigation.

    It should render the same regardless whether the page is hidden from main navigation or not.

    Did you try my example from above? :) If that does not work then try removing the xsl:if statement - Now the "current" class should be applied to all li elements and it should be visible no matter the page you're visiting - right? If so then it's just a matter of figuring out how to set the "current" class.

    /Jan

  • Paul Griffiths 370 posts 1021 karma points
    Jan 15, 2015 @ 14:41
    Paul Griffiths
    0

    Hi Jan,

    Sorry i had to nip out.

    Yes i have tried your above suggestion and i did not have much luck with it sorry. if i remove the [not(umbracoNaviHide = 1)] from the for each statement then it works as it should but there is still a problem here because when viewing the website in a browser although you can only see the nav items that i want

    • Home
    • About us
    • Our Services
    • Our Drivers
    • Contact us

    The other nav items such as news, privacy, sitemap, t&c's etc are there but are being hidden because of the styling which is not the best approach.

    This little issue seems to have go me lol

    Thanks for your help so far Jan

    Paul

  • Jan Skovgaard 11280 posts 23678 karma points MVP 10x admin c-trib
    Jan 15, 2015 @ 16:38
    Jan Skovgaard
    0

    Hi Paul

    Ok, so the menu renders correctly now? But now the bottom items are being hidden? Is that correct?

    How are you rendering those? What does the code for that look like?

    /Jan

  • Paul Griffiths 370 posts 1021 karma points
    Jan 15, 2015 @ 17:08
    Paul Griffiths
    0

    Hi Jan,

    The menu renders with every single level 1 node inside it which is not what i want. it basically looks like this now on hover but now shows the current page.

    On hover

    enter image description here

    on current page

    enter image description here

    the code is exactly the same as above with the following taken out of the for each loop [not(umbracoNaviHide = 1)].

    Many thanks

    Paul

  • Paul Griffiths 370 posts 1021 karma points
    Jan 15, 2015 @ 18:48
    Paul Griffiths
    0

    I think i will just have to leave it hacked for now until i find a solution. Not ideal hiding the nav items when viewing on a browser but its the only way i can get the nav working when viewing on a mobile device.

    Thanks for all your help

    Paul

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Jan 15, 2015 @ 20:39
    Chriztian Steinmeier
    2

    Hi Paul,

    To get this to work, you need to think differently - you're using umbracoNaviHide to hide stuff from the main nav - but at the same time, you want to be able to highlight those items on a mobile device... but if they're not in the nav, you can't show them.

    To me, umbracoNaviHide has always meant: "Don't ever show this in navigations, RSS feeds, or searches" - so I wouldn't use that property for this. I'd do this:

    • Add a showInFooterNav property to pages
    • When rendering the main nav, put a .mobileOnly CSS class on all pages with the showInFooterNav checked
    • Only allow those to be visible in the main nav when they have the .mobileOnly class (and they're shown on a mobile device, of course :-)

    (Presuming I've understood the problem correctly, of course):

    <xsl:param name="currentPage" />
    <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
    
    <xsl:template match="/">
        <xsl:variable name="onHomePage" select="$currentPage/@id = $siteRoot/@id" />
        <nav>
            <ul>
                <!-- Home node -->
                <li>
                    <xsl:if test="$onHomePage"><xsl:attribute name="class">current</xsl:attribute></xsl:if>
                    <a href="/" title="Home">
                        <xsl:if test="$onHomePage"><xsl:attribute name="class">selected</xsl:attribute></xsl:if>
                        <span>Home</span>
                    </a>
                </li>
    
                <!-- Doing this in two "sets" to set the `.last` class correctly -->
                <!-- 1. Normal pages for main nav -->
                <xsl:apply-templates select="$siteRoot/*[@isDoc][not(umbracoNaviHide = 1)][not(showInFooterNav = 1)]" />
    
                <!-- 2. Add extra pages for the mobile nav -->
                <xsl:apply-templates select="$siteRoot/*[@isDoc][showInFooterNav = 1]" />
            </ul>
        </nav>
    </xsl:template>
    
    <!-- Generic template for nav items -->
    <xsl:template match="*[@isDoc]">
        <xsl:variable name="inPath" select="descendant-or-self::*[@id = $currentPage/@id]" />
        <xsl:variable name="isLast" select="position() = last()" />
        <xsl:variable name="liClass">
            <xsl:if test="showInFooterNav = 1">mobileOny </xsl:if>
            <xsl:if test="$inPath">current </xsl:if>
            <xsl:if test="$isLast">last</xsl:if>
        </xsl:variable>
        <li>
            <xsl:if test="normalize-space($liClass)">
                <xsl:attribute name="class"><xsl:value-of select="normalize-space($liClass)" /></xsl:attribute>
            </xsl:if>
            <a href="{umbraco.library:NiceUrl(@id)}">
                <xsl:if test="$inPath"><xsl:attribute name="class">selected</xsl:attribute></xsl:if>
                <span><xsl:value-of select="@nodeName" /></span>
            </a>
        </li>
    </xsl:template>
    

    This requires that your "mobile only" items can be placed last (or first) in the mobile nav. Otherwise, the .last class takes some more work to figure out correctly :-)

    Ask away about anything in there you'd like to have explained better!

    /Chriztian

  • Paul Griffiths 370 posts 1021 karma points
    Jan 15, 2015 @ 21:28
    Paul Griffiths
    100

    Hey Chriztian,

    Thanks for getting in touch regarding this issue. Yes it appears that you are understanding my issue as your response seems to make sense to me.

    Your explination of umbraoNaviHide makes a lot of sense and i agree with everything that you mention and this has been taken on board for future reference.

    I will take a look into implementing what you have suggested with putting a .mobileOnly class on just pages that have the showIn footer checked which i already have on my doc type because i have these pages displayed in the footer.

    Hopefully your xslt will help me solve this one, lets see :)

    Thanks again mate, i will be back soon with the outcome.

    Thanks

    Paul

  • Paul Griffiths 370 posts 1021 karma points
    Jan 16, 2015 @ 20:35
    Paul Griffiths
    0

    Hi Chriztian,

    I have been looking at this and i think that i am on the right lines now with the new xslt you provided. Im still working away at it at the minute though.

    Ive marked the wrong post as solved how do i undo this so i can mark your post as solved please?

    Cheers

    Paul

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Jan 16, 2015 @ 20:48
    Chriztian Steinmeier
    0

    Hi Paul,

    I don't think you can change that when it's done, but don't worry about that - you won't get any undeserved karma points for it, so no one will come after you for doing it :-) It's the friendly community, remember? ;-D

    Come back if you need extra help with any of it,

    /Chriztian

  • Paul Griffiths 370 posts 1021 karma points
    Jan 16, 2015 @ 21:08
    Paul Griffiths
    0

    Hi chriztian

    Again appologies for marking the wrong post, good job you lot are so friendly, yes I will give you a shout if I'm struggling with this one but I think you have helped lots with what you wrote for me.

    Your a top man :)

    Paul

Please Sign in or register to post replies

Write your reply to:

Draft