Bobmd
Bobmd

Reputation: 135

Sort Struct in ColdFusion on Values ASC

How can I sort this structure by the values in ASC order?

<cfset dStruct = createObject("java", "java.util.LinkedHashMap").init()>
<cfquery name="gds" datasource="#application.dsn#">
    SELECT * FROM stores WHERE region_id = #arguments.retailer_id# 
    ORDER BY client_loc ASC
</cfquery>

<cfoutput query="gds">
    <cfset var dStru = { "#gds.storeid#" = "#gds.client_loc# - #gds.city#, #gds.state#" }>
    <cfset StructAppend( dStruct, dStru )>
</cfoutput>

<cfset StructSort(dStruct,"textnocase","asc")>
....
<cfreturn SerializeJSON(dStruct) />

The results then populate a drop down. Here are the results:

struct
299 | ASH041 - ONTARIO, CA
300 | ASH042 - CLEARWATER, FL
301 | ASH044 - TAMPA, FL
302 | ASH046 - ORLANDO, FL
303 | ASH047 - SARASOTA, FL
304 | ASH048 - TAMPA, FL
305 | ASH002 - HUNTINGTON STN., NY

If it was sorting correctly, ASH002 would be the first result, but it appears to be sorting on the KEY instead of the VALUE. Is there a way to sort by the values?

I also tried this...

<cfset dStruct = createObject("java", "java.util.LinkedHashMap").init() />

Either way produces the same results. Here is a screenshot of the results...

screenshot

Here is the jquery that populates the select menu.

        $.ajax({
            url: "/functions.cfc",
            cache: false, 
            type: "get",
            dataType: "json",
            data: {method: "getstoresbyretailer", retailer_id: (retailer_id)}, //get stores
            success: function (data) { 

                var $select = $('#storeid'); 
                $select.find('option').remove();

                $.each(data,function(key, value) {
                    $select.append('<option value=' + key + '>' + value + '</option>');
                });

            }
        }); 

Upvotes: 1

Views: 867

Answers (2)

Bobmd
Bobmd

Reputation: 135

thanks so much for your help. I figured out a solution... by returning an array of objects.

function getstoresbyretailer(retailer_id) { 

$.ajax({
    url: "/functions.cfc",
    cache: false, 
    type: "get",
    dataType: "json",
    data: {method: "getstoresbyretailer", retailer_id: (retailer_id)}, 
    success: function (data) { 

        var $select = $('#storeid'); 
        $select.find('option').remove();

        $.each(data, function(key, value) {
            $select.append('<option value=' + value.storeid + '>' + value.store + '</option>');
        });
    }
}); 
}   

And the ColdFusion Function...

<cffunction name="getstoresbyretailer" access="remote" returnformat="json" output="no">
    <cfargument name="retailer_id" type="numeric" required="yes">

    <cfset var dArray = []>
    <cfif arguments.retailer_id neq 0>

        <cfquery name="gds" datasource="#application.dsn#">
            SELECT * FROM stores WHERE region_id = #arguments.retailer_id# 
            ORDER BY client_loc ASC
        </cfquery>

        <cfif gds.recordcount>

            <cfoutput query="gds">
                <cfset dStru = { "storeid" = "#gds.storeid#", "store" = "#gds.client_loc# - #gds.city#, #gds.state#" }>
                <cfset ArrayAppend( dArray, dStru )>
            </cfoutput>

        </cfif>

    </cfif>

    <cfreturn SerializeJSON(dArray) />
</cffunction>

Figured someone might be able to use this one day.

Upvotes: 1

Alex
Alex

Reputation: 7833

Ordering within your SQL statement would be the best solution here:

ORDER BY storeid, client_loc, city, state

and then loop over your query and generate the options.


But to answer your question:

If you want to sort an unlinked struct (dStruct) and keep an ordered struct, you have to use a linked struct (LinkedHashMap):

<cfset sortedKeys   = structSort(dStruct, "textnocase", "asc")>
<cfset sortedStruct = createObject("java", "java.util.LinkedHashMap").init()>

<cfloop array="#sortedKeys#" index="key">
    <cfset sortedStruct[key] = dStruct[key]>
</cfloop>

<cfoutput>

    <select>
        <cfloop collection="#sortedStruct#" item="key">
            <option>#encodeForHtml(sortedStruct[key])#</option>
        </cfloop>
    </select>

</cfoutput>

Note that using cfdump does not display the real order of a linked struct.

Upvotes: 4

Related Questions