
Copy link to clipboard
Copied
Hi I have been able of course to sort a standard list with the ListSort function like so:
<cfset myList=ListSort("wango, jango, tango, cash","TextNoCase","ASC")>
<cfoutput>#myList#</cfoutput>
which results in just a text with no html:
cash, jango, tango, wango
But, what if I need to sort a dynamic list thats being displayed from another page with a cfinclude?
<cfset myList=ListSort("some_lists","TextNoCase","ASC")>
I've tried wrapping the cfinclude in a cfsavecontent variable="some_lists"> and then output that variable with no luck. Can this not be done? or am I going about this all wrong? Thanks for any help in advance!
1 Correct answer
teedoffnewbie wrote:
Now it seems to sort the Vendors correct and throughout the complete application!
Yes, the vendors are sorted by these lines creating a sorted list of the vendor keys and then looping for that list, rather the the verdor structure itself.
<cfset vendorList = listSort(structKeyList(item.vendors),"textnocase","ASC")> <cfloop list= '#vendorList#' index = 'vendorName'>
teedoffnewbie wrote:
but obvioulsy there was something it didnt like.
Yes, it did not like the line you comment
...Copy link to clipboard
Copied
teedoffnewbie wrote:
<cfset myList=ListSort("some_lists","TextNoCase","ASC")>
Is that the actual line of code you used which would try and sort a list that contains the single literal string "some_lists".
Or did you use an actual variable in the function which would look like.
<cfset myList = ListSort(some_lists,"textNoCase","ASC")>
Or one of the less clean versions using pound|hash|# symbols
<cfset myList = ListSort(#some_lists#,"textNoCase","ASC")>
<cfset myList = ListSort("#some_lists#","textNoCase","ASC")>

Copy link to clipboard
Copied
ahh sorry, yes some_lists would have been a variable. I actually thought I was close just now. I changed the ListSort function to:
<cfsavecontent variable = "myList">
<cfinclude template="vendorProductList.cfm">
</cfsavecontent>
<cfset myList = ListSort("#myList#","TextNoCase","ASC","li")>
<cfoutput>#myList#</cfoutput>
I thought this worked at first, but it doesnt because my lists are somewhat unique. They are generated by jQuery and called back and displayed with an ajax function.
When I use the "li" as a delimiter, I get the lists ordered alphabetically I think, but it also seems to throw a bunch of junk in with it. Characters like < and misplaced letters like the following:
- l>
ale-type:none;">
jango
tango
wango
meproductusyou
Plus that doesn work period since each dynamcially created ul will have list items of its own, then the next ul will have its own list items. So really that would simply order the FIRST li items in order, then order the "sub" list items underneath as you can see above with "meproductusyou".
But if I leave out the li as a delimiter, I get no sorting whatsoever.

Copy link to clipboard
Copied
I should try to explain in better detail I guess...lol
These lists are user defined. The user enters data in input fields. Then these values are passed to my action.cfm page and looped through in a two dimensional array...so a loop nested in another loop.
The results of the loops are then saved with cfsavecontent and sent to a temp file....vendorProductList.cfm and this file is sent back to my page as a cfinclude.
Now, again the user has the option of creating as many ul's as she needs via jQuery, there's no way to determine in advance how many ul's nor how many list items are going to be sorted.
Copy link to clipboard
Copied
ListSort() is going to have a very difficult time working with your data. It is designed to handle simple text lists with clearly defined delimiters.
You could get closer by adding the "<",">", and "/" characters to your delimiters. But that is still going to leave the "class...." data as part of your list.
What you really have is an HTML LIST fragment for data.
IF you are trying to sort these after the fact, you might be able to acomplish something with the XSLT transformation on the HTML as XML data. But that can be quite a learning curve if you have never tried that kind of XSLT coding before.
Otherwise the best bet, would be to sort the data in your JQuery backend as you are building the include file rather then trying to do it afterwords.

Copy link to clipboard
Copied
Yes I agree with you about the ListSort handling data like I have. So back to using jQuery..lol which I had already tried, but didnt seem to work either. It almost seems like I can get the jQuery sorting function to work ONCE and then only if I create my extra lists in just a precise manner. But after that it doesnt work at all.
Not sure if you can help with the jQuery sort function I have, and I'm quite sure this isnt the right forum for that as well.

Copy link to clipboard
Copied
ilssac wrote:
ListSort() is going to have a very difficult time working with your data. It is designed to handle simple text lists with clearly defined delimiters.
You could get closer by adding the "<",">", and "/" characters to your delimiters. But that is still going to leave the "class...." data as part of your list.
What you really have is an HTML LIST fragment for data.
IF you are trying to sort these after the fact, you might be able to acomplish something with the XSLT transformation on the HTML as XML data. But that can be quite a learning curve if you have never tried that kind of XSLT coding before.
Otherwise the best bet, would be to sort the data in your JQuery backend as you are building the include file rather then trying to do it afterwords.
Ok, so for the last 5 days or so, I've been trying to use jQuery to sort the lists as they are generated. As I posted above, I have managed to get the list(s) sorted once they are called for and displayed with my ajax click event. However, I am not able to figure out how to keep the list(s) sorted through the rest of my application.
The first page of my "pageBuilder" application contains all the jQuery to build the dynamic lists. Once the lists are populated. The submit button(ajax) sends the values to my action page. The action page then loops through the lists and saves the output to a temporary file called vendorProductList.cfm by way of a cffile. Each time the lists are populated, this vendorProductList.cfm file is overwritten. Then the contents of the vendorProductList.cfm are displayed on the original page as a cfinclude.
My jQuery sort function works fine ON the original page when the lists are displayed, but once I pass them onto my preview page...builderAction.cfm, so that the user can preview how the page will look before finalizing everything, the lists get reverted back to the original order so that they are not alphabetized.
Obviously, I'm either taking the wrong approach once again, or maybe I have not placed the jQuery sort function in the right file/place within my application.
I would greatly appreciate some hints or shoves in the right direction..lol. Thanks in advance once again.
Copy link to clipboard
Copied
teedoffnewbie wrote:
Obviously, I'm either taking the wrong approach once again, or maybe I have not placed the jQuery sort function in the right file/place within my application.
jQuery is mostly a client side technology. If you are planning on using jQuery, you will need to use it everywhere in the client where this data is displayed. Unless you want to spend the effort to figure out how to capture the sorted output generated by the jQuery function and send it back to the server (with jQuery AJAX functions most likely) to be saved on the server for future viewing events.
teedoffnewbie wrote:
The action page then loops through the lists and saves the output to a temporary file called vendorProductList.cfm by way of a cffile. Each time the lists are populated, this vendorProductList.cfm file is overwritten. Then the contents of the vendorProductList.cfm are displayed on the original page as a cfinclude.
But, I would pobably just do it at this step of the process. While you are looping through the lists and writing them to the temporary file. Why don't you add logic to have the loops go through the data in alphabetical order. Then whenever your vendorProductList.cfm page is displayed the data will be in the desired order.

Copy link to clipboard
Copied
function(){return A.apply(null,[this].concat($A(arguments)))} jQuery is mostly a client side technology. If you are planning on using jQuery, you will need to use it everywhere in the client where this data is displayed. Unless you want to spend the effort to figure out how to capture the sorted output generated by the jQuery function and send it back to the server (with jQuery AJAX functions most likely) to be saved on the server for future viewing events.
Yes I realize jQuery is client side, and I've tried sorting the lists on each page of my application. One thing I notice, which is why I think I'm not using the sort function in the right place, is that even with the sorting being performed within the loop, the vendorProductList.cfm page still shows the lists in the order they were populated. Meaning not alphabetically. But again, once they are displayed, they ARE in alphabetical order. So, then I tried sorting AFTER they are displayed and even as the lists are displayed on the next "preview" page. I think though the problem is that the lists are displayed FROM the vendorProductList.cfm as an include.
function(){return A.apply(null,[this].concat($A(arguments)))} But, I would pobably just do it at this step of the process. While you are looping through the lists and writing them to the temporary file. Why don't you add logic to have the loops go through the data in alphabetical order. Then whenever your vendorProductList.cfm page is displayed the data will be in the desired order.
Yes again, I am sorting while looping through the lists. But then once the loops output to an unordered list and saved to the vendorProductList.cfm, those lists are not sorted at all.
As far as adding logic, I'm not exactly sure what you mean. Can you please explain further. Again, the action.cfm page is looping through and using:
<cffile action = "write"
nameconflict = "overwrite"
file = "#expandPath('vendorProductList.cfm')#"
output = "#vendorProductList#">
to save the output of the loops. Thanks again for all your help ilssac!
Copy link to clipboard
Copied
As I recall from the previous topic, you have some rather convoluted logic to turn nested list data from a text input box into HTML nested lists.
You would add logic to that step that would sort the order of the lists as they are being turned into the HTML. Then when you write that file, you would be done.
Doing so afterwards is much harder. But of course you are already working extra hard because you are using less then optimal User Interface design (a single text area rather then dynamic related select boxes) and a poor back end (a temporary text file rather then a properly normalized database tables).
You have now spent five days working on a solution that would have been trivial and done in an hour or two at most, if you had just bit the bullet and gone with best practices. That was what many commentators tried to point out to you in your last thread. You are spending a lot of time (which really does equal lots of money in our business) trying for the "simple" solution. That is neither simple nor quick!
But back to your attmepted solution. You will need to add logic to sort the data. How you do that depends on how you want to work with the information. The '"easiest" (I say with some trepidation) I think would be to do two loops. One loop to turn the nested text lists into nested arrays. You could then apply array sorts to each level of the nest as you output the array into the final HTML version of the data. But this would probably require a recursive function, and I don't know what your experience with one of those is.
Otherwise, you will need to beable to loop through the nested lists AND the HTML output, so that you can insert new elements into the correct place in the output to have the results be alphabetical.
A third option, that I mentioned earlier, is to consider the HTML data as XML data (which is valid as they share the same structure in this instance) and then use XSLT transformation code to sort the HTML into the desired alpabetical output.
Any of these options would happen on the action page BEFORE you write the output to the temporary file.

Copy link to clipboard
Copied
I apologize, I thought I had specified somewhere that I have reworked my application to use dynamic form inputs, not select lists, but at least now its not a generic text area utilizing faulty and difficult to use delimiters.
So with that said, you mentioned sorting BEFORE the lists are written to the temp file, which is what I am doing. Let me show you my list forms:
<form>
<div id="items">
<fieldset class="product-grouping">
<legend>Item 1</legend>
<div class="vendor" style="padding-left: 30px;"> <span>Vendor: </span>
<input type="text" class="vendor-input" name="vendor" />
<a href="#" class="add-vendor">add vendor</a>
<div class="vendor-products" style="padding-left: 60px;">
<div class="product"> <span>Product: </span>
<input type="text" class="product-input" name="product" />
<a href="#" class="add-product">add product</a> </div>
</div>
</div>
</fieldset>
</div>
<input type="button" id="add-item" value="add item" />
<input type="button" id="submit" value="submit" />
</form>
and yes I now have two loops..nested. One looping through the heading2 form values(vendors), the other loop looping through the list items(products).
<cfsavecontent variable = "vendorProductList">
<cfoutput>
<cfset results = deserializeJSON(url.data)>
<cfloop collection = '#results#' item = 'itemName' >
<cfset item = results[itemName]>
<cfloop collection = '#item.vendors#' item = 'vendorName'>
<h2>#vendorName#</h2>
<ul class="myList">
<cfset productArray = item.vendors[vendorName]>
<cfloop array='#productArray#' index = 'productName'>
<li style="margin-left:30px;">#productName#</li>
</cfloop>
</ul>
</cfloop>
</cfloop>
<script type="text/javascript">
$(function() {
var items = [];
$('h2').each(function() {
items.push($(this).text());
});
items.sort(function(a, b) {
a = a.toLowerCase();
b = b.toLowerCase();
return (a < b ? -1 : (a > b ? +1 : 0));
});
$('h2').each(function(i) {
$(this).text(items);
});
});</script>
</cfoutput>
</cfsavecontent>
<cffile action = "write"
nameconflict = "overwrite"
file = "#expandPath('vendorProductList.cfm')#"
output = "#vendorProductList#">
Once this out put is sent to the vendorProductList.cfm, and I view the file, the lists are not sorted at all. But once the file is called with the include, they somehow are sorted. I assmed this was because as I have it now, the lists are output and THEN sorted, which is saved to the temp file ALONG with the sort function script. But I have tried sorting the form values BEFORE the loops as well.
I hope that clears up a bit. Sorry for the confusion...lol I'm confused enough for the both of us!
Copy link to clipboard
Copied
<cfloop collection = '#results#' item = 'itemName' > <cfset item = results[itemName]> <cfloop collection = '#item.vendors#' item = 'vendorName'> <h2>#vendorName#</h2> <ul class="myList"> <cfset productArray = item.vendors[vendorName]> <cfloop array='#productArray#' index = 'productName'> <li style="margin-left:30px;">#productName#</li> </cfloop> </ul> </cfloop> </cfloop>
Ok, now this won't be so hard. Instead of looping through the raw collections (aka structures). Loop through alpahbatized lists of the structure keys.
RAW untested code only typed here, but should get you close.
<cfloop collection = '#results#' item = 'itemName' > <cfset item = results[itemName]> <cfset vendorList = listSort(structKeyList(item.vendors),"textnocase","ASC")> <!---NEW LINE---> <cfloop list= '#vendorList#' index = 'vendorName'> <h2>#vendorName#</h2> <ul class="myList"> <cfset productArray = item.vendors[vendorName]> <cfset productArray = arraySort(productArray)> <!---NEW LINE---> <cfloop array='#productArray#' index = 'productName'> <li style="margin-left:30px;">#productName#</li> </cfloop> </ul> </cfloop> </cfloop>

Copy link to clipboard
Copied
Yes I think I tried this originally, which is why I started this thread. This throws an error "500 parameter validation error for ARRAYSORT function"
I had the listsort function similar to what you previously suggested, but I think I wasn't sorting the arrays, but just the list items.
Copy link to clipboard
Copied
teedoffnewbie wrote:
This throws an error "500 parameter validation error for ARRAYSORT function.
Which is a good time to head for the documentation and look up the arraysort() function.
http://livedocs.adobe.com/coldfusion/8/htmldocs/functions_a-b_21.html
And see that I had typed it in wrong. That it requires a sort type parameter and that it does not return the array, but rather just a true or false success status.
Thus the proper syntax for that line is:
<cfset testBoolean = arraySort(productArray,"textnocase")> <!---NEW LINE--->
OR
<cfset testBoolean = arraySort(productArray,"textnocase","ASC")> <!---NEW LINE--->
P.S., It would probably be a good idea to turn on verbose error messages if you have not done so.

Copy link to clipboard
Copied
Well if you mean from within Firebug, I think its on. I can click on the error line and get a more detailed error report, which is still throwing a 500 error. Also says something about 2 to 3 parameters expected in ARRAYSORT.
Parameter validation error for the ARRAYSORT function.
The function accepts 2 to 3 parameters.
The error occurred in C:\ColdFusion8\wwwroot\replacementlightbulb\pageBuilder\action.cfm: line 29
27 : <ul class="myList">
28 : <cfset productArray = item.vendors[vendorName]>
29 : <cfset productArray = arraySort(productArray)>
30 : <!---NEW LINE--->
31 : <cfloop array='#productArray#' index = 'productName'>
Ok let me ask this. Your code you suggested above. We have a variable defined...productArray = item.vendor[vendorname]
Then we have the same variable but set to equal arraySort(productArray)
Maybe I'm confused, but is this going to sort on the values of products? I really am only concerned presently with sorting the vendor values which is in the heading2 tags.

Copy link to clipboard
Copied
Ok I think I have it!! My code:
<cfset results = deserializeJSON(url.data)>
<cfloop collection = '#results#' item = 'itemName' >
<cfset item = results[itemName]>
<cfset vendorList = listSort(structKeyList(item.vendors),"textnocase","ASC")>
<!---NEW LINE--->
<cfloop list= '#vendorList#' index = 'vendorName'>
<h2>#vendorName#</h2>
<ul class="myList">
<cfset productArray = item.vendors[vendorName]>
<cfset productArray = arraySort(productArray)>
<!--- NEW LINE--->
<cfloop array='#productArray#' index = 'productName'>
<li style="margin-left:30px;">#productName#</li>
</cfloop>
</ul>
</cfloop>
</cfloop>
Then I commented out the line: <cfset productArray = arraySort(productArray)>.
Now it seems to sort the Vendors correct and throughout the complete application! Maybe there is way way to sort an array of structs, if this was the issue at all anyway, but obvioulsy there was something it didnt like.
Copy link to clipboard
Copied
teedoffnewbie wrote:
Now it seems to sort the Vendors correct and throughout the complete application!
Yes, the vendors are sorted by these lines creating a sorted list of the vendor keys and then looping for that list, rather the the verdor structure itself.
<cfset vendorList = listSort(structKeyList(item.vendors),"textnocase","ASC")> <cfloop list= '#vendorList#' index = 'vendorName'>
teedoffnewbie wrote:
but obvioulsy there was something it didnt like.
Yes, it did not like the line you commented out, because I did not use the array sort function correctly.
<cfset productArray = arraySort(productArray)>
Should have been:
<cfset testBoolean = arraySort(productArray,"textnocase")>
That I posted in my earlier reply. This line would also sort the products under each vendor.
Copy link to clipboard
Copied
teedoffnewbie wrote:
Well if you mean from within Firebug,
No I mean in the ColdFusion administrator where one can tell ColdFusion to provide a more complete description of errors and exceptions.

Copy link to clipboard
Copied
Well I have enabled detailed error reporting in cf admin, but this was an error alert within my ajax function. I saw in my admin the check box that enabled ajax debugging with the cfdebug flag passed in the url, but not very familiar with that. Not sure of thats what you were talking about anyway.

Copy link to clipboard
Copied
Hey ilssac, thanks again for all your help! It's working like a charm now! My lists are sorted as they are suppose to be, and staying that way throughout the application.
I was originally using the listsort and arraysort functions, but gave up because I was under tha impression the listsort function only worked with simple text lists. So I obviously wasn't using the correct syntax. Anyway, thanks for setting me straight!
Copy link to clipboard
Copied
teedoffnewbie wrote:
I was under tha impression the listsort function only worked with simple text lists.
It does only work with simple text lists. The structKeyList() function returns all the keys (indexes) of a structure as a simple list.

Copy link to clipboard
Copied
lol Yes...thats the part of the function(syntax) I was not using. I was trying I think to use the listsort with my list variable name:
ListSort"(#myList#", "TextNoCase", "ASC")
which is just simply sorting a simple list and not a struct.
Now that I see it and how it works, it makes perfect sense! Thanks again!
Copy link to clipboard
Copied
The documentation on any ColdFusion list function will tell you what happens when you use something like "li" as a delimiter.

Copy link to clipboard
Copied
Yes you are correct..lol. Either way, with or without any delimiter in the listsort function, as ilssac said I think this is the wrong approach. Butthe jQuery sort approach isnt working with how my lists are created either. thanks all!
Copy link to clipboard
Copied
Still on the subject of delimiters, I expected you to test with
<cfset myList = ListSort(myList,"TextNoCase","ASC","#chr(13)##chr(10)#")>


-
- 1
- 2