Copied to clipboard

Flag this post as spam?

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


  • boedlen 7 posts 27 karma points
    Sep 27, 2012 @ 08:56
    boedlen
    0

    XSLT - Sorting countries

    Hi, 

    I have a large number of dealers created as subnodes to my "Dealers" page.

    Each of my dealer have a countrycode property like DK, GB or SE, and in my dictionary i have a similar entries for each unique countrycode. They look like:

    CountryName.DK
    CountryName.GB
    CountryName.SE

    This allows my to ge the localized country name like in my XSLT:

    <xsl:variable name="countryName" select="umbraco.library:GetDictionaryItem(  concat('CountryName.', $currentNode/countryCode)  )"/>

    My problem is that i need to create a unique list of countries sorted by the localized countryname. I've found some XSLT that gives me the unique countries, but i can see how i can implement sorting.

    Hope someone has done this before and can help me out.

    Here's what i use for the unsorted unique list:

    <select name="dealer-country">
    <option>Select country</option>
    <xsl:for-each select="umbraco.library:GetXmlNodeById($source)//countryCode[not(.=preceding::countryCode)]">
    <xsl:choose>
    <xsl:when test="$cat = category">
    <option value="{.}">
    <xsl:variable name="trans" select="umbraco.library:GetDictionaryItem(  concat('CountryName.', .)  )"/>
    <xsl:choose>
    <xsl:when test="string-length($trans) &gt; 0">
    <xsl:value-of select="$trans" />
    </xsl:when>
    <xsl:otherwise>
    <xsl:value-of select="."/>
    </xsl:otherwise>
    </xsl:choose>
    </option>
    </xsl:when>
    <xsl:otherwise>
    <option value="{.}">
    <xsl:variable name="trans" select="umbraco.library:GetDictionaryItem(  concat('CountryName.', .)  )"/>
    <xsl:choose>
    <xsl:when test="string-length($trans) &gt; 0">
    <xsl:value-of select="$trans" />
    </xsl:when>
    <xsl:otherwise>
    <xsl:value-of select="."/>
    </xsl:otherwise>
    </xsl:choose>
    </option>
    </xsl:otherwise>
    </xsl:choose>
    </xsl:for-each>
    </select>

    Again, i hope someone has can give me som pointers, i'm pretty blank.

    Regards
      Martin

     

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Sep 27, 2012 @ 10:45
    Chriztian Steinmeier
    0

    Hi Martin,

    First off, I hope you're aware that the Dictionary is there ideally for you to *not* have to do those concatenation things? E.g. - you should be able to just have a single "CountryName" key, and then fill in the values for the Languages you've set up. Umbraco will give you the one that's applicable for the branch of the tree you're in. (If you are aware but your setup can't use it for some reason, please ignore :-).

    Secondly, the two main branches in your code (xsl:when $cat = category and the corresponding xsl:otherwise) are identical (which could be because you left something out) - which makes it even harder to see what you're trying to do. (Incidentally, the category you're testing will be taken from the countryCode element being processed - is that what you're expecting?)

    Anyway, here's a condensed version including the xsl:sort :

    <xsl:variable name="uniques" select="umbraco.library:GetXmlNodeById($source)//countryCode[not(. = preceding::countryCode)]" />
    <select name="dealer-country">
        <option>Select country</option>
        <xsl:for-each select="$uniques">
            <xsl:sort select="umbraco.library:GetDictionaryItem(concat('CountryName', .))" data-type="text" order="ascending" />
    
            <xsl:variable name="translatedName" select="umbraco.library:GetDictionaryItem(concat('CountryName', .))" />
    
            <xsl:variable name="displayName">
                <xsl:value-of select="normalize-space($translatedName)" />
                <xsl:if test="not(normalize-space($translatedName))">
                    <xsl:value-of select="." />
                </xsl:if>
            </xsl:variable>
    
            <xsl:choose>
                <!-- Where should this <category> come from? -->
                <xsl:when test="$cat = category">
                    <option value="{.}">
                        <xsl:value-of select="$displayName" />
                    </option>
                </xsl:when>
                <xsl:otherwise>
                    <option value="{.}">
                        <xsl:value-of select="$displayName   " />
                    </option>
                </xsl:otherwise>
            </xsl:choose>
        </xsl:for-each>
    </select>

    /Chriztian

  • Boudewijn Somer 1 post 21 karma points
    Sep 27, 2012 @ 10:56
    Boudewijn Somer
    0

    Hi Martin,

    I have 2 suggestions:

    1. The easy way: Use jquery to sort your dropdown.

    function sortDropDownListByText(selectId){
       
    var foption = $('#'+ selectId +' option:first');
       
    var soptions = $('#'+ selectId +' option:not(:first)').sort(function(a, b){
           
    return a.text == b.text ?0: a.text < b.text ?-1:1
       
    });
        $
    ('#'+ selectId).html(soptions).prepend(foption);              

    };

    2. Or build up a temp XML file in your XSLT or do your sorting on this:

        <xsl:variable name="sortabledealer">
            <root xmlns="">
                <xsl:for-each select="umbraco.library:GetXmlNodeById($source)//countryCode[not(.=preceding::countryCode)]">
                    <dealer name="{umbraco.library:GetDictionaryItem(  concat('CountryName.', .)  )}" value={trans}>
                    </dealer>
                </xsl:for-each>
            </root>
        </xsl:variable>

    Then in your template match:

    <xsl:variable name="nodes" select="msxml:node-set($sortabledealer)" />
    <
    xsl:for-each select="$nodes/root/dealer">
           <xsl:sort select="@name" order="ascending"/>

    Hope this brings you on the right track.

    Regards,
    Boudewijn

  • boedlen 7 posts 27 karma points
    Sep 28, 2012 @ 09:21
    boedlen
    0

    Hi Chriztian,

    My initial XSLT was basicly a copy past from the internet, so i didn't quite understand why it worked it just did.

    Your XSLT did exactly what i needed and i actually think i understand how it works.

    But could you tell why this works?

    <xsl:sortselect="umbraco.library:GetDictionaryItem(concat('CountryName', .))"data-type="text"order="ascending"/>

    I though it had to be the elemnt name like countryCode.

    // Martin

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Sep 28, 2012 @ 10:24
    Chriztian Steinmeier
    0

    Hi Martin,

    The select on a sort statement is actually an XPath expression like anywhere else - it's executed for every element in the enclosed for-each (or apply-templates), and the resulting value is used for sorting the complete set. You can even use multiple sort statements to achieve the final sorting...

    Hope that explains it :-)

    /Chriztian

Please Sign in or register to post replies

Write your reply to:

Draft