Copied to clipboard

Flag this post as spam?

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


  • Eddie Foreman 215 posts 288 karma points
    Jul 15, 2010 @ 14:54
    Eddie Foreman
    0

    Building a menu by RadioBox Value

    Hi All

    Not sure on the best way to describe this, but here goes !!!

    I have a stucture of

    Home
      - products
        - item 1 - level 3
        - item 2
        - item 3
        - item 4
        ...

    The product group is set by a value from a RadioBox datatype, the values are 13, 14 and 15.  I need use the item nodes and create a menu which mimics;

    Group 1
        - item 2 - value of 13
        - item 3 - value of 13
    Group 2
        - item 1- value of 14
    Group 3
        - item 4 - value of 15

    I've roughly put together the following xslt, although manily to show the mark-up I have to work with.

      <xsl:variable name="level" select="2"/>

      <xsl:template match="/">
       
        <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1' and string(data[@alias='showInFooter']) != 1]">
       
       
        </xsl:for-each>
       
        <!-- Structure to group products -->
          <ul>
            <li id="qroup1">
              <a href="#">Product Group One</a>
              <ul>
                <!-- Insert if group value = 13 -->
                <xsl:if test="./data [@alias='productType'] = '13'">
                  <li>
                      <a href="{umbraco.library:NiceUrl(@id)}">
                        <xsl:value-of select="@nodeName"/>
                      </a>
                  </li>
                </xsl:if>
              </ul>
            </li>
            <li id="group2">
              <a href="#" class="selectDrop">Product Group Two</a>
              <ul>
                <!-- Insert if group value = 14 -->
                <xsl:if test="./data [@alias='productType'] = '14'">
                  <li>
                    <a href="{umbraco.library:NiceUrl(@id)}">
                      <xsl:value-of select="@nodeName"/>
                    </a>
                  </li>
                </xsl:if>
              </ul>
            </li>
            <li id="group3">
              <a href="#" class="selectDrop">Product Group Three</a>
              <ul>
                <!-- Insert if group value = 13 -->
                <xsl:if test="./data [@alias='productType'] = '15'">
                  <li>
                    <a href="{umbraco.library:NiceUrl(@id)}">
                      <xsl:value-of select="@nodeName"/>
                    </a>
                  </li>
                </xsl:if>
              </ul>
            </li>
          </ul>
      </xsl:template>

    Would really apericate some advice on how to tackle this?

    Thanks

    Eddie

  • Bogdan 250 posts 427 karma points
    Jul 15, 2010 @ 17:03
    Bogdan
    0

    Hi Eddie,

    I would make 3 variables for each group:

      <xsl:variable name="productsNodeId"
     select="1234" />
      <xsl:variable name="group1" select="umbraco.library:GetXmlNodeById($productsNodeId)/node[data [@alias='productType'] = '13']" />
      <xsl:variable name="group2" select="umbraco.library:GetXmlNodeById($productsNodeId)/node[data [@alias='productType'] = '14']" />
      <xsl:variable name="group3" select="umbraco.library:GetXmlNodeById($productsNodeId)/node[data [@alias='productType'] = '15']" />

    then for example for group 1:

    <li id="qroup1">
             
    <a href="#">Product Group One</a>
             
    <ul>
               
    <xsl:for-each select="$group1">
                 
    <li>
                     
    <a href="{umbraco.library:NiceUrl(current()/@id)}">
                       
    <xsl:value-of select="current()/@nodeName"/>
                     
    </a>
                 
    </li>
                </xsl:for-each>
              </ul>
           
    </li>

     

    I hope this helps.

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Jul 15, 2010 @ 17:04
    Matt Brailsford
    1

    Ok, so I'm assuming what you want, is what you have now, but dynamic right?

    If that's the case, then what you'll want to do is use the umbraco.library:GetPreValues method to retreive the list of options then loop through them, something like:

    <ul>
    <xsl:for-each select="umbraco.library:GetPreValues($yourDataTypeId)//preValue">
    <li id="{concat('group', position())}">
      <a href="#">
    <xsl:value-of select="."/>

    </a>
      <ul>
       <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1' and string(data[@alias='showInFooter']) != 1] and [@alias='productType'] = ./@id">
       <li>
        <a href="{umbraco.library:NiceUrl(@id)}">
        <xsl:value-of select="@nodeName"/>
        </a>
       </li>
       </xsl:for-each>
      </ul>
    </li>

    </xsl:for-each>
    </ul>

    I've not tested it, as I just typed it straight in, but should be pretty much right.

    Let me know if you have any problems.

    Matt

  • Eddie Foreman 215 posts 288 karma points
    Jul 15, 2010 @ 18:05
    Eddie Foreman
    0

    Hi Matt

    I got a working version similar to bfi's solution, but I like the looks of using GetPreValues as it seems more efficent.

    So I copied your code and added the products parent page id of 1110, which I've added to GetPreValues(...).  I had to make a change to the second for-each as I was getting an exception. 

        <ul>      
    <xsl:for-each select="umbraco.library:GetPreValues(1110)//preValue">
            <li id="{concat('group', position())}">
              <a href="#">
                <xsl:value-of select="."/>
              </a>
              <ul>
                  <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=$level]/node [string(data [@alias='umbracoNaviHide']) != '1' and string(data[@alias='showInFooter']) != '1' and string(alias='productType') = ./@id]">
                  <li>
                    <a href="{umbraco.library:NiceUrl(@id)}">
                      <xsl:value-of select="@nodeName"/>
                    </a>
                  </li>
                </xsl:for-each>
              </ul>
            </li>
          </xsl:for-each>
        </ul>


    Could you have a look, as I'm getting an empty <ul> tag? 

    Thanks

    Eddie

     

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Jul 15, 2010 @ 18:39
    Matt Brailsford
    0

    Hey Eddie,

    Looks like you'll need to make a slight change to the last filter, it should be

    string(data[alias='productType']) = ./@id

    Hope this helps.

    Matt

  • Eddie Foreman 215 posts 288 karma points
    Jul 15, 2010 @ 19:12
    Eddie Foreman
    0

    Hi Matt

    Still no joy,  

    Not sure if this makes a difference, but the menu is only used on the item pages?

    Thanks

    Eddie

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Jul 15, 2010 @ 19:21
    Matt Brailsford
    0

    Hey Eddie,

    I'd probably start by removing the filters on the second for-each and re-adding them back one at a time to see where the issue is. If you start with something like:

    $currentPage/ancestor-or-self::node [@level=$level]/node

    And see if you get a list of nodes at the right level to start with, then you can re-apply filters untill you find the problem.

    Matt

  • Eddie Foreman 215 posts 288 karma points
    Jul 15, 2010 @ 19:52
    Eddie Foreman
    0

    Hi Matt

    The correct menu is created with:

    $currentPage/ancestor-or-self::node [@level=(2)]/node


    Any other filters produce the empty ul.  After reading my first post, it reads as if the productType could be on the landing page, when in fact it's  property of each item page.

    Thanks

    Eddie

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Jul 15, 2010 @ 20:05
    Matt Brailsford
    0

    Hey Eddie,

    Don't really understand what you meant in your last post, but if you are getting the right level from your previus code, does this give you a list of items for group 1?

    $currentPage/ancestor-or-self::node [@level=(2)]/node[data[@alias='productType'] = '13']

    Matt

  • Eddie Foreman 215 posts 288 karma points
    Jul 15, 2010 @ 20:10
    Eddie Foreman
    0

    Hi Matt

    Some progress, I'm getting all of the options of the productType, displayed as a menu?

    XSLT:

        <ul>
    <xsl:for-each select="umbraco.library:GetPreValues(1113)//preValue">
    <li id="{concat('group', position())}">
    <a href="#">
    <xsl:value-of select="."/>
    </a>
    <ul>
    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=(2)]/node [string(data[alias='productType']) = ./@id]">
    <li>
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:value-of select="@nodeName"/>
    </a>
    </li>
    </xsl:for-each>
    </ul>
    </li>
    </xsl:for-each>
    </ul>

    Generated mark-up:

    <ul>
    <li id="group1">
    <a href="#">Choose Group</a>
    <ul style="display: block;">
    <li id="group2">
    <a href="#" class="">Group One</a>
    <ul style="display: block;">
    <li id="group3">
    <a href="#" class="">Group 2</a>
    <ul style="display: block;">
    <li id="group4">
    <a href="#" class="">Group 3</a>
    <ul style="display: block;">
    </ul>
    </li>
    </ul>
    </li>
    </ul>
    </li>
    </ul>
    </li>
    </ul>


    Thanks

    Eddie

  • Eddie Foreman 215 posts 288 karma points
    Jul 15, 2010 @ 20:21
    Eddie Foreman
    0

    Hi Matt

    Just added updated the xslt to:

        <ul>
    <xsl:for-each select="umbraco.library:GetPreValues(1113)//preValue">
    <li id="{concat('group', position())}">
    <a href="#">
    <xsl:value-of select="."/>
    </a>
    <ul>
    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=(2)]/node[data[@alias='productType'] = '13']">
    <li>
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:value-of select="@nodeName"/>
    </a>
    </li>
    </xsl:for-each>
    </ul>
    </li>
    </xsl:for-each>
    </ul>

     

    Which as created the following:

    <ul>
    <li id="group1">
    <a href="#">Choose group</a>
    <ul style="display: none;">
    <li><a href="/products/item-group1.aspx">An Item</a></li>
    </ul>
    </li>
    <li id="group2">
    <a href="#">Group 1</a>
    <ul style="display: none;">
    <li><a href="/products/item-group1.aspx">An Item</a></li>
    </ul>
    </li>
    <li id="group3">
    <a href="#">Group 2</a>
    <ul style="display: none;">
    <li><a href="/products/item-group1.aspx">An Item</a></li>
    </ul>
    </li>
    <li id="group4">
    <a href="#">Group 4</a>
    <ul style="display: none;">
    <li><a href="/products/item-group1.aspx">An Item</a></li>
    </ul>
    </li>
    </ul>

     

    Which is almost there, but uses the same UL for all the links (product type value of 13).  I also need to exlcude the first li with choose group, guess this is simply done testing the position?

    Thanks

    Eddie

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Jul 15, 2010 @ 20:22
    Matt Brailsford
    0

    Hey Eddie,

    Can you update

    string(data[alias='productType'])

    to

    string(data[@alias='productType'])

    (Notice the the @ symbol) and let me know if thats any better?

    Matt

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Jul 15, 2010 @ 20:26
    Matt Brailsford
    0

    RE "Choose group", yea, I'd do an xsl:if round the whole thing, and check that ./@id isn't blank and is greater than 0

    Matt

  • Eddie Foreman 215 posts 288 karma points
    Jul 15, 2010 @ 20:53
    Eddie Foreman
    0

    Hi Matt

    Cool, had a go and to date the xslt is:

          <xsl:for-each select="umbraco.library:GetPreValues(1113)//preValue">
    <xsl:if test="position() &gt; 1">
    <li id="{concat('group', position())}">
    <a href="#">
    <!-- if page in nested ul, is it possible to add a class to this -->
    <xsl:value-of select="."/>
    </a>
    <ul>
    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=(2)]/node[data[@alias='productType'] = 15]">
    <li>
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:if test="$currentPage/@id = current()/@id">
    <xsl:attribute name="class">select</xsl:attribute>
    </xsl:if>
    <xsl:value-of select="@nodeName"/>
    </a>
    </li>
    </xsl:for-each>
    </ul>
    </li>
    </xsl:if>
    </xsl:for-each>

    Also added a not in the opening a tag, to see if its possible to add a class (current), when the nested ul contains a current page.

    Thanks

    Eddie

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Jul 15, 2010 @ 21:47
    Matt Brailsford
    0

    Hey Eddie,

    Not 100% sure, but you could try something like this

    <xsl:if test="$currentPage/ancester-or-self:node/data[@alias='productType'] = ./@id">
    <xsl:attribute name="class">select</xsl:attribute>
    </xsl:if>

    That might work.

    Matt

  • Eddie Foreman 215 posts 288 karma points
    Jul 16, 2010 @ 00:08
    Eddie Foreman
    0

    Hi Matt

    Have tried it works if I set the second for-each to:

    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=(2)]/node[data[@alias='productType'] = ./@id]">

    The class is appended, to the last ul, but all of the ul are nested within each other, so

        <ul>
          <li id="group2">
            <a></a>
            <ul>
              <li id="group3">
                <a></a>
                <ul>
                  <li id ="group4">
                    <a class="select"></a>
                    <ul> Empty!!! </ul>
                  </li>
                </ul>
              </li>
            </ul>
          </li>
        </ul>

    Current xslt looks like:

    ...
    <ul>
    <xsl:for-each select="umbraco.library:GetPreValues(1113)//preValue">
    <xsl:if test="position() &gt; 1">
    <li id="{concat('group', position())}">
    <a href="#">
    <xsl:if test="$currentPage/ancestor-or-self::node/data[@alias='productType'] = ./@id">
    <xsl:attribute name="class">bingo</xsl:attribute>
    </xsl:if>
    <xsl:value-of select="."/>
    </a>
    <ul>
    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=(2)]/node[data[@alias='productType'] = ./@id]">
    <li>
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:if test="$currentPage/@id = current()/@id">
    <xsl:attribute name="class">select</xsl:attribute>
    </xsl:if>
    <xsl:value-of select="@nodeName"/>
    </a>
    </li>
    </xsl:for-each>
    </ul>
    </li>
    </xsl:if>
    </xsl:for-each>
    </ul>
    ...

    Not sure, how to amend the filters in the second for-each so that the <ul> are not nested?

    Thanks for all your time, seems so close.

    Eddie

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Jul 16, 2010 @ 09:57
    Matt Brailsford
    0

    Hey Eddie,

    Really can't see what would cause the constant nesting for every level, as all the tags seem to be nested correctly. The output from the above should be allong the lines of

    <ul>
        <li><a href="#">Group 1</a>
            <ul>
                <li><a href="#">Link 1</a></li>
                <li><a href="#">Link 2</a></li>
                <li><a href="#">Link 3</a></li>
            </ul>
        </li>
        <li><a href="#">Group 2</a>
            <ul>
                <li><a href="#">Link 1</a></li>
                <li><a href="#">Link 2</a></li>
                <li><a href="#">Link 3</a></li>
            </ul>
        </li>
        <li><a href="#">Group 3</a>
            <ul>
                <li><a href="#">Link 1</a></li>
                <li><a href="#">Link 2</a></li>
                <li><a href="#">Link 3</a></li>
            </ul>
        </li>
    </ul>

    Is this the structure you are after?

    Matt

  • Eddie Foreman 215 posts 288 karma points
    Jul 16, 2010 @ 11:33
    Eddie Foreman
    0

    Hi Matt

    Yes, that is the stucture that I'm after.  As a test I've moved the second for-each so that it wraps around the nested <ul>, which has fixed the nesting issue, producing:

    <ul>
       
    <li><a href="#">Group 1</a>

       
    </li>
       
    <li><a href="#">Group 2</a>

       
    </li>
       
    <li><a href="#">Group 3</a>

       
    </li>
    </ul>

    If I change:

    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=(2)]/node[data[@alias='productType'] = ./@id]">

    to:

    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=(2)]/node[data[@alias='productType'] = '13']">

    Each grouping has the correct stucture, although each group has the same link. 

    Thanks

    Eddie

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Jul 16, 2010 @ 11:50
    Matt Brailsford
    1

    Ok, I think we might need to put the prevalues id into a variable before the second for each. Lets try

    <xsl:variable name="preValueId" select=./@id />
    <xsl:for-each
    select="$currentPage/ancestor-or-self::node [@level=(2)]/node[data[@alias='productType'] = $preValueId]">

    Matt

  • Eddie Foreman 215 posts 288 karma points
    Jul 16, 2010 @ 17:15
    Eddie Foreman
    0

    Hi Matt

    Putting the id into a variable, done the trick : -)

    Thanks again

    Eddie

     

  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Jul 16, 2010 @ 17:21
    Matt Brailsford
    0

    Awesome!

    Glad we finally got there =)

    Matt

  • Eddie Foreman 215 posts 288 karma points
    Jul 17, 2010 @ 09:06
    Eddie Foreman
    0

    Hi Matt

    Very please, thanks.  Just one last bit of the puzzle, I need to add a current class, to the nested ul - see note in xslt, although I could fix this with JavaScript.

        <ul>
    <xsl:for-each select="umbraco.library:GetPreValues(1113)//preValue">
    <xsl:if test="position() &gt; 1">
    <li id="{concat('group', position())}">
    <a href="#">
    <xsl:if test="$currentPage/ancestor-or-self::node/data[@alias='productType'] = ./@id">
    <xsl:attribute name="class">selectDrop</xsl:attribute>
    </xsl:if>
    <xsl:value-of select="."/>
    </a>
    <xsl:variable name="preValueId" select="./@id" />
    <ul><!-- add class of current, if child page = current -->
    <xsl:for-each select="$currentPage/ancestor-or-self::node [@level=(2)]/node[data[@alias='productType'] = $preValueId]">
    <li>
    <a href="{umbraco.library:NiceUrl(@id)}">
    <xsl:if test="$currentPage/@id = current()/@id">
    <xsl:attribute name="class">select</xsl:attribute>
    </xsl:if>
    <xsl:value-of select="@nodeName"/>
    </a>
    </li>
    </xsl:for-each>
    </ul>
    </li>
    </xsl:if>
    </xsl:for-each>
    </ul>

    Guess  I should open this as a new topic?

    Thanks

    Eddie

  • Sebastiaan Janssen 5060 posts 15522 karma points MVP admin hq
    Jul 17, 2010 @ 09:15
    Sebastiaan Janssen
    0

    Is that not the same thing that you already do with adding the class "select" to the anchor tag? In that case, change your ul to something like this:

    <ul>
      <xsl:if test="$currentPage/@id = current()/@id">
        <xsl:attribute name="class">current</xsl:attribute>>
      </xsl:if>
  • Matt Brailsford 4125 posts 22223 karma points MVP 9x c-trib
    Jul 17, 2010 @ 10:50
    Matt Brailsford
    1

    Hey Eddie / Sebastiaan,

    I think you should just be able to reuse the if statement used to add a class to the group heading.

    <xsl:if test="$currentPage/ancestor-or-self::node/data[@alias='productType'] = ./@id">
       
    <xsl:attribute name="class">current</xsl:attribute>
    </xsl:if>

    @sebastiaan - that wouldn't unfortunatley work, as you are not in the second for-each at that point.

    Matt

  • Sebastiaan Janssen 5060 posts 15522 karma points MVP admin hq
    Jul 17, 2010 @ 10:53
    Sebastiaan Janssen
    0

    You're right, I missed the for-each loop!

  • Eddie Foreman 215 posts 288 karma points
    Jul 17, 2010 @ 13:00
    Eddie Foreman
    0

    Hi Matt & Sebastiaan,

    I tried reusing the if statement earlier on and got an error, seems to work now!!!  Must of been the early start...

    Thanks again to you both,

    Eddie

Please Sign in or register to post replies

Write your reply to:

Draft