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
    Mar 06, 2014 @ 19:52
    Paul Griffiths
    0

    Help with xslt search

    Hi guys I have the following xslt which takes values from a search form that I created. This works brilliant but I have two slight problems which im hoping someone can help me with.

    <!--Form field variables-->
            <xsl:variable name="strtype" select="umbraco.library:RequestForm('ctl00$ctl00$ctl00$ContentPlaceHolderDefault$SearchForm_3$ddlTypes')"/>
            <xsl:variable name="strlocation" select="umbraco.library:RequestForm('ctl00$ctl00$ctl00$ContentPlaceHolderDefault$SearchForm_3$ddlLocation')"/> 
            <xsl:variable name="strcapacity" select="umbraco.library:RequestForm('ctl00$ctl00$ctl00$ContentPlaceHolderDefault$SearchForm_3$ddlGuestCapacity')"/>
            <xsl:variable name="strkeywords" select="Exslt.ExsltStrings:uppercase(umbraco.library:RequestForm('ctl00$ctl00$ctl00$ContentPlaceHolderDefault$KeywordForm_3$txtKeywords'))" /> 
    
        <xsl:for-each select="$sectionNode[contains((FunctionTypes), $strtype) and ($strlocation = location) and ($strcapacity = capacity) and (not(normalize-space($strkeywords))) ] | $sectionNode[contains(Exslt.ExsltStrings:uppercase(pageKeywords), $strkeywords) and normalize-space($strkeywords)]">
    

    My problem is the user has to select a value in four for a any result to appear. What I would like is too allow the user to just search on one condition for example if they only entered a value in location e.g liverpool and then searched the results would show every single result that is located in liverpool. As it stands now i have to put in a value for every option to get a search result back for liverpool.

    My other prob is because i am dynamically generating the ddl it is generating the html as this = ctl00$ctl00$ctl00$ContentPlaceHolderDefault$SearchForm_3$ddlLocation however is there a better way to set an id on the element and target that in the xslt?

    Hope this is clear and some may be able to help me.

    Thank you

    Paul

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Mar 06, 2014 @ 22:10
    Chriztian Steinmeier
    1

    Hi Paul,

    You're doing the right kind of thinking, actually. I usually throw in an intermediate step for clarity:

    <!-- Form field variables -->
    <xsl:variable name="strtype" select="umbraco.library:RequestForm('ctl00$...$ddlTypes')"/>
    <xsl:variable name="strlocation" select="umbraco.library:RequestForm('ctl00$...$ddlLocation')"/> 
    <xsl:variable name="strcapacity" select="umbraco.library:RequestForm('ctl00$...$ddlGuestCapacity')"/>
    <xsl:variable name="strkeywords" select="Exslt.ExsltStrings:uppercase(umbraco.library:RequestForm('ctl00$...$txtKeywords'))" /> 
    
    <!-- Collect nodes if Form variable was set -->
    <xsl:variable name="typeNodes" select="$sectionNode[contains(FunctionTypes, $strtype)][normalize-space($strtype)]" />
    <xsl:variable name="locationNodes" select="$sectionNode[location = $strlocation][normalize-space($strlocation)]" />
    <xsl:variable name="capacityNodes" select="$sectionNode[capacity = $strcapacity][normalize-space($strcapacity)]" />
    <xsl:variable name="keywordNodes" select="$sectionNode[contains(Exslt.ExsltStrings:uppercase(pageKeywords), $strkeywords)][normalize-space($strkeywords)]" />
    
    <!-- Iterate through the combined set of nodes -->
    <xsl:for-each select="$typeNodes | $locationNodes | $capacityNodes | $keywordNodes">
        <!-- Etc. -->
    </xsl:for-each>
    

    With regards to the stupid .NET ids - isn't there a property somewhere that puts you in charge of the ID? Something like ClientID or HtmlId ?

    I have hated those IDs since the dawn of time :-)

    Let me know if it doesn't work!

    /Chriztian

  • Paul Griffiths 370 posts 1021 karma points
    Mar 06, 2014 @ 22:16
    Paul Griffiths
    0

    Hi Chriztian

    Thanks for the reply matey I will give it a whirl tommorrow morning and let you know how it goes!

    Once again you come up trumps with regards to xslt :)

    Awesome

    Thanks

    Paul

  • Paul Griffiths 370 posts 1021 karma points
    Mar 07, 2014 @ 09:24
    Paul Griffiths
    0

    Good morning chriztian,

    I have tried the code that you have suggested but im still not getting results to display :( (it may be a mistake from me?). Just to make it clearer for you. The alias of my properties are as follows

    cityTown(property) = strlocationNodes venueFunctionTypes(property) = strtypeNodes guestCapacity(property) = strcapacityNodes pageKeywords = strpageKeywordsNodes (poor naming conventions i know lol)

    <xsl:output method="xml" omit-xml-declaration="yes" />
    
    <xsl:param name="currentPage"/>
    
        <!--General variables-->
        <xsl:variable name="sectionNode" select="$currentPage/ancestor-or-self::*/Venues/Country/Region/County/CityTown/Venue"/>
    
        <!--Form field variables-->
        <xsl:variable name="strtype" select="umbraco.library:RequestForm('ctl00$ctl00$ctl00$ContentPlaceHolderDefault$SearchForm_3$ddlFunctionTypes')"/>
        <xsl:variable name="strlocation" select="umbraco.library:RequestForm('ctl00$ctl00$ctl00$ContentPlaceHolderDefault$SearchForm_3$ddlLocation')"/> 
        <xsl:variable name="strcapacity" select="umbraco.library:RequestForm('ctl00$ctl00$ctl00$ContentPlaceHolderDefault$SearchForm_3$ddlGuestCapacity')"/>
        <xsl:variable name="strkeywords" select="Exslt.ExsltStrings:uppercase(umbraco.library:RequestForm('ctl00$ctl00$ctl00$ContentPlaceHolderDefault$KeywordForm_3$txtKeywords'))" />     
    
        <!-- Collect nodes if Form variable was set -->
        <xsl:variable name="typeNodes" select="$sectionNode[contains(venueFunctionTypes, $strtype)][normalize-space($strtype)]" />
        <xsl:variable name="locationNodes" select="$sectionNode[contains(cityTown, $strlocation)][normalize-space($strlocation)]" />
        <xsl:variable name="capacityNodes" select="$sectionNode[contains(guestCapacity, $strcapacity)][normalize-space($strcapacity)]" />
        <xsl:variable name="keywordNodes" select="$sectionNode[contains(Exslt.ExsltStrings:uppercase(pageKeywords), $strkeywords)][normalize-space($strkeywords)]" />
    
    
    <xsl:template match="/">
    
    <!-- Iterate through the combined set of nodes -->
    <xsl:for-each select="$typeNodes | $locationNodes | $capacityNodes | $keywordNodes">
    
       <xsl:sort select="venueName" order="ascending" />        
        <div class="venue-list">
            <h2><xsl:value-of select="venueName"/></h2>
            <p><xsl:value-of select="venueShortDescription"/></p>       
    
        </div>
    
    
    </xsl:for-each>
    
    </xsl:template>
    
    </xsl:stylesheet>
    

    I have three venues set as the location liverpool and if i only select liverpool from the location ddl I have no results returned.

    Sorry if ive missed something. I tried to pput contains in the capacity and location nodes as it didnt work without.

    thanks

    Ps you were right with the other problem it was clientidMode="static"

    <asp:DropDownList ID="ddlTest" runat="server" ClientIDMode="Static"></asp:DropDownList>
    

    Paul

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Mar 07, 2014 @ 11:10
    Chriztian Steinmeier
    0

    Hi Paul,

    Okay - just to be sure - what does the ClientIDMode do? Do you get to set your own IDs?

    The fieldnames you're referencing in the RequestForm() calls should match the generated name attributes on the form fields...

    /Chriztian

  • Paul Griffiths 370 posts 1021 karma points
    Mar 07, 2014 @ 11:28
    Paul Griffiths
    0

    Hi

    The dropdown list has two attributes one called id and one called name and when the html is generated the name and id were getting rendered as ctl00$ctl00$ctl00$ContentPlaceHolderDefault$SearchForm3$ddlFunctionTypes but in the code file they are just set as ddlFunctionTypes. All the clientIDMode does is remove this ctl00$ctl00$ctl00$ContentPlaceHolderDefault$SearchForm3$ so when the html is rendered it is just id="ddlFunctionTypes".

    All this now matches so i'm unsure why the search results xslt is not generating anything if the user selects any amount of options from the drop down list options.

    The only time i get search results to appear is when i use the keywords search. Do you think i could be loosing the form values when the search button is selected?

    thanks

    Paul

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Mar 07, 2014 @ 11:38
    Chriztian Steinmeier
    0

    Hi Paul,

    Actually - I think it's because of some PostBack thing... the DropDownList probably does an Ajax POST which means the XSLT is never processed with values in the Form.

    You can test that by writing the $strtype and $strlocation etc. variables directly out in the HTML...

    /Chriztian

  • Paul Griffiths 370 posts 1021 karma points
    Mar 07, 2014 @ 11:47
    Paul Griffiths
    0

    Hi

    Yeah you are right with this placed in the xslt, no html is generated so it looks like it is not being processed :(.

    <xsl:value-of select="$strtype"/>
    
    <xsl:value-of select="$strlocation"/>
    

    Cheers

    Paul

  • Paul Griffiths 370 posts 1021 karma points
    Mar 07, 2014 @ 12:38
    Paul Griffiths
    0

    Hi Chriztian,

    I now have it working i think i made a mistake somewhere i wrote it all out again and i can now generate results.

    Problem i have now is that i have 3 venues with the following info stored on the system.

    name = venue1 location = Liverpool type = weddings capacity = 250

    name = venue2 location = Wrexham type = weddings capacity = 500

    name = venue3 location = Liverpool type = weddings capacity = 750

    when i search by just location e.g Liverpool only venue 1 and venue 2 displays which is great. However, when i search by liverpool and type weddings all venues show. Is there a way to filter only out only the venues that match all cases? e.g if I search

    location = liverpool type = weddings capacity = 250

    only venue 1 should show, however if i search if i take away the capacity value and search venue 1 and three should show as they match two conditions.

    Would this be an xsl:if test somewhere?

    Sorry to keep going on and your feedback is very much appreciated :)

    Thanks

    Paul

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Mar 07, 2014 @ 13:02
    Chriztian Steinmeier
    100

    Hi Paul,

    No worries - I love to help out :-)

    You can do that for sure - it's just a matter of filtering further down, e.g. to grab only the venues that match both type and location, you can do:

    <!-- Combine $typeNodes with all nodes from $locationNodes that are also in the $typeNodes set -->
    <xsl:for-each select="$typeNodes | $locationNodes[@id = $typeNodes/@id]">
        ...
    </xsl:for-each>
    

    Note that the order matters - so you'll need to decide which criteria takes precedence over the others.

    /Chriztian

  • Paul Griffiths 370 posts 1021 karma points
    Mar 07, 2014 @ 13:07
    Paul Griffiths
    0

    Hi Chriztian

    Brilliant!!! I shall give that a whirl and let you know how I do :)

    Thanks

    Paul

  • Paul Griffiths 370 posts 1021 karma points
    Mar 07, 2014 @ 18:07
    Paul Griffiths
    0

    Hi Chriztian,

    Again apologies for getting back but i cant seem to work this one out (not for trying tho) and xslt has fried my brain for the day lol.

    I have been thinking about the logic that i need and im just getting confused with what you have suggested (it doesnt take much when it comes to xslt lol)

    if the user just selects liverpool as the location then i want every single venue located in liverpool to show in the results.

    enter image description here

    Next if the user selects liverpool as the location and wedding as the function type i want only the venues who are located in liverpool and host the function type wedding to show in the results. If the venue is located in liverpool but doesn't host weddings then i don't want it to show or if the venue does host weddings but is not located in liverpool then again i dont want it to show either.

    enter image description here

    Again if the user now selects all three values, liverpool as the location, weddings as the function type and upto 200 guests as the as the capacity all i want to display in the search results is venues who match all three conditions. so if a venue is located in liverpool and it does hold upto 200 guests but it doesnt hold the function type wedding then i dont want it to show in the results.

    enter image description here

    Now im not sure if im thinking about this logic right (probably due to my lack of knowledge in xslt) but what i was thinking that the following 7 possibilities need to be considered.

    option 1

    Action = user selects just the location Result = fetch back everything that only matches the location specified

    option 2

    Action = user selects location and function type Result = fetch back everything that only matches the location and function type specified

    option 3

    Action = user selects location and capacity Result = fetch back everything that only matches the location and capacity specified

    option 4

    Action = user selects location, function type and capacity Result = fetch back everything that only matches the location, function type and capacity specified

    option 5

    Action = user selects just the function type Result = fetch back everything that only matches the function type specified

    option 6

    Action = user selects function type and capacity Result = fetch back everything that only matches the function type and capacity specified

    option 7

    Action = user selects just the capacity Result = fetch back everything that only matches the capacity specified

    So if the following is used to grab only the venues that match both type and location specified how do i implement all the other tests? has each for each loop with all the code have to be duplicated for each possibility?

    <!-- Combine $typeNodes with all nodes from $locationNodes that are also in the $typeNodes set -->
    <xsl:for-each select="$typeNodes | $locationNodes[@id = $typeNodes/@id]">
        ...
    </xsl:for-each>
    

    sorry to go on, but i feel the clearer i can try to explain then it may help you understand my problem.

    Thanks mate

    Have a good weekend

    Paul

  • Roger 195 posts 474 karma points
    Mar 11, 2014 @ 11:31
    Roger
    0

    Hi chriztian,

    I've been trying to help Paul out on this one and struggling to allow results to be pulled back based on any combination of the drop down boxes. Could you possibly help please?

    Many thanks

  • Chriztian Steinmeier 2800 posts 8790 karma points MVP 8x admin c-trib
    Mar 11, 2014 @ 12:11
    Chriztian Steinmeier
    0

    Hi guys,

    Would love to help out more - just been very busy with actual work :(

    Quick answer to the above, though: No, you shouldn't have multiple for-each statements - you should end up with one set of nodes comprising the combined results. (And I know that's the heart of the problem :-)

    Basically: Collect nodes from each of the variables (as showed earlier) and then combine using the technique where you only select nodes from another set if their @id matches one in another.

    /Chriztian

  • Roger 195 posts 474 karma points
    Mar 11, 2014 @ 17:02
    Roger
    1

    Ok, based on the idea of checking whether node id's match in the sets, this will work:

    <xsl:for-each select="$locationNodes[(not(normalize-space($typeNodes))) and (not(normalize-space($capacityNodes)))] | $typeNodes[(not(normalize-space($locationNodes))) and (not(normalize-space($capacityNodes)))] | $capacityNodes[(not(normalize-space($locationNodes))) and (not(normalize-space($typeNodes)))] | $locationNodes[(@id = $typeNodes/@id) and (@id = $capacityNodes/@id)] | $locationNodes[(@id = $capacityNodes/@id) and (not(normalize-space($typeNodes)))] | $typeNodes[(@id = $capacityNodes/@id) and (not(normalize-space($locationNodes)))]">
    

    Thanks, Rog

  • Paul Griffiths 370 posts 1021 karma points
    Mar 11, 2014 @ 17:44
    Paul Griffiths
    0

    Cheers for the help boys!

    I'm a happy man now! #DeStress for the time being ha

    Paul

Please Sign in or register to post replies

Write your reply to:

Draft