jameskane
asked on
reordering a list
I have two lists dynamically generated from a form. EG
List one (text1,text2,text3,text4)
List two (2,4,1,3)
The first list is created by the user selecting items on a form using the checkbox. On selecting the item, he/she then enters an order number into a field adjoining the checkbox.
The form is submitted and I have two lists, as above. Text1 has a list order of 2, text 2 has a list order of 4, text3 has a list order of 1 and text4 has a list order of 3.
The objective is to create a new version of list one, where the order of the elements is 1,2,3, 4 - vrs their current order of 2,4,1, 3. The reordered list is then used to create a table listing of list1 elements, ordered by 1,2,3,4.
Can someone give me a pointer as to how I might do this. First thought is to create a two dimensional array, sort it and then generate a new version of list1 ?
Many thanks for any help
james
List one (text1,text2,text3,text4)
List two (2,4,1,3)
The first list is created by the user selecting items on a form using the checkbox. On selecting the item, he/she then enters an order number into a field adjoining the checkbox.
The form is submitted and I have two lists, as above. Text1 has a list order of 2, text 2 has a list order of 4, text3 has a list order of 1 and text4 has a list order of 3.
The objective is to create a new version of list one, where the order of the elements is 1,2,3, 4 - vrs their current order of 2,4,1, 3. The reordered list is then used to create a table listing of list1 elements, ordered by 1,2,3,4.
Can someone give me a pointer as to how I might do this. First thought is to create a two dimensional array, sort it and then generate a new version of list1 ?
Many thanks for any help
james
Assuming all of the entries are valid, it's certainly possible. But this structure has the potential for a few pitfalls. For example, if a user skips an entry - or enters an invalid value like "12" (there aren't 12 elements). What about using a different mechanism for the ordering, like a multi-select list with options to shift items up or down. Is that possible?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks as always agx for the rapid response !
I am not too worried about the fragility. The user will be presented with the ordered list - and if it does not look correct he can go back to the form and change the order numbers he entered.
I did come across the idea of being able to shift items up and down, but could not figure it out !! I certainly looked impressive. The scenario I had in mind was that the user would see the list (as per current thinking) after submitting the form, but with the up and down arrows to allow for manual sorting. The mechanism would be supported by the two lists uploaded to the action page from the form.
If you know of a pointer to a support for this I would appreciate it.
Will try your solution in a couple of hours, but it looks good to me !!
James
I am not too worried about the fragility. The user will be presented with the ordered list - and if it does not look correct he can go back to the form and change the order numbers he entered.
I did come across the idea of being able to shift items up and down, but could not figure it out !! I certainly looked impressive. The scenario I had in mind was that the user would see the list (as per current thinking) after submitting the form, but with the up and down arrows to allow for manual sorting. The mechanism would be supported by the two lists uploaded to the action page from the form.
If you know of a pointer to a support for this I would appreciate it.
Will try your solution in a couple of hours, but it looks good to me !!
James
>> The reordered list is then used to create a table listing of list1 elements, ordered by 1,2,3,4
this makes me think you are actually storing the data as comma-delimited list in your table...
is that right? if it is, i strongly advise you to re-think your approach before it is too late.
if you were to normalize your db and store each list item as a separate record in a linked table, then you would not need to worry about re-ordering the list: just store the item's position in item_ordinal column.
if you are storing the list as column value in your db, i can explain more on how to change it.
Azadi
this makes me think you are actually storing the data as comma-delimited list in your table...
is that right? if it is, i strongly advise you to re-think your approach before it is too late.
if you were to normalize your db and store each list item as a separate record in a linked table, then you would not need to worry about re-ordering the list: just store the item's position in item_ordinal column.
if you are storing the list as column value in your db, i can explain more on how to change it.
Azadi
ASKER
That's right azadi - that table is a repository for the different selections (playlists) that the user creates from his inventory of cd tracks. If he wants a playlist from the repository, he brings up the repository table and, selects the playlist and then it is dynamically generated from the stored list.
Unfortunately this project is not a green field project - he has 2500 tracks stored on an access database which has no sense at all of what is needed for a database application. He uses some of the access functionality to create reports... which great difficulty. There were no key fields or anything like that.
Each track has a title, and he entered those with commas !!!!! So I had to do a big cleanup to rid myself of the commas. Comma cleaning is something I build into the action page so I am not going to get into difficulty if he forgets not to enter commas. I find that the spaces dont matter.
Having said all of that, now you have me worried !!
Unfortunately this project is not a green field project - he has 2500 tracks stored on an access database which has no sense at all of what is needed for a database application. He uses some of the access functionality to create reports... which great difficulty. There were no key fields or anything like that.
Each track has a title, and he entered those with commas !!!!! So I had to do a big cleanup to rid myself of the commas. Comma cleaning is something I build into the action page so I am not going to get into difficulty if he forgets not to enter commas. I find that the spaces dont matter.
Having said all of that, now you have me worried !!
Oh, I thought you meant meant html table.. not db table. I totally agree with Azadi. Normalize. Storing csv lists is just bad news. Unfortunately, I have to head out now. But I'm sure Azadi will explain it :)
ASKER
Thanks very much, that works. Could you let me know how to change the order from descending to ascending - needs a desc tag somewhere ?
Thanks also to you both for your advise on the design. I am not too worried on reflection about putting the listing into the database. Its a bounded action in the context of the total application. The main processing does not require its use - which is along standard lines;
Thanks again.
Thanks also to you both for your advise on the design. I am not too worried on reflection about putting the listing into the database. Its a bounded action in the context of the total application. The main processing does not require its use - which is along standard lines;
Thanks again.
ASKER
Azadi,
there seems to be a problem with the sorting code. It refuses to work correctly for lists of more that 5 items. Its not at all clear to me why this should be the case.
SO, the first example below works, but the second does not.
<cfset list1 = "textone,texttwo,textthree ,textfour, xxx">
<cfset list2 = "2,4,1,3,5">
<cfset list1 = "textone,texttwo,textthree ,textfour" >
<cfset list2 = "2,4,1,3">
Maybe its something obvious to your eye, but its a mystery to me !
james
there seems to be a problem with the sorting code. It refuses to work correctly for lists of more that 5 items. Its not at all clear to me why this should be the case.
SO, the first example below works, but the second does not.
<cfset list1 = "textone,texttwo,textthree
<cfset list2 = "2,4,1,3,5">
<cfset list1 = "textone,texttwo,textthree
<cfset list2 = "2,4,1,3">
Maybe its something obvious to your eye, but its a mystery to me !
james
> how to change the order from descending to ascending
If you mean reverse the order of the final list:
http://cflib.org/index.cfm?event=page.udfbyid&udfid=51
If you mean reverse the order of the final list:
http://cflib.org/index.cfm?event=page.udfbyid&udfid=51
ASKER
Thanks very much, that is very interesting, but another thing.The problem is that azadi's code works fine for 4 item lists, but not for lists with more than 4. Just cant figure that out
James
James
Did azadi post code? I thought only I did. It should have no problem with more than 4 items. It works for me. Does the data itself contain commas? Maybe that's throwing it off.
ASKER
sorry agx, getting late... loosing it a bit.
If you replace the list 1 and List 2 in the example code with the one in my previous mail you will see the problem. Its not a case of commas, I am clean on that. I tried it with list items which had spaces and apostrophes and that worked, no problem. Its just that when it goes over 4 items, it gets lost. If you just replace your example lists with the ones I sent you will see it
again, apologies for the mix up
james
If you replace the list 1 and List 2 in the example code with the one in my previous mail you will see the problem. Its not a case of commas, I am clean on that. I tried it with list items which had spaces and apostrophes and that worked, no problem. Its just that when it goes over 4 items, it gets lost. If you just replace your example lists with the ones I sent you will see it
again, apologies for the mix up
james
I must be misunderstanding :) because in both cases I see what I would expect:
newList = text2,text4,text1,text3,xx x
newList = texttwo,textfour,textone,t extthree
What do you expect to see in the first and second case?
newList = text2,text4,text1,text3,xx
newList = texttwo,textfour,textone,t
What do you expect to see in the first and second case?
ASKER
<cfset list1 = "textone,texttwo,textthree ,textfour, xxx">
<cfset list2 = "2,4,1,3,5"
for the above I expect
xxx,texttwo,textfour,texto ne,textthr ee
the code does not seem to cope with the fifth item XXX, which I would have expected to be first, ahead of texttwo
James
<cfset list2 = "2,4,1,3,5"
for the above I expect
xxx,texttwo,textfour,texto
the code does not seem to cope with the fifth item XXX, which I would have expected to be first, ahead of texttwo
James
> the code does not seem to cope with the fifth item XXX
No, I must be misunderstanding the logic you're trying to apply ;-) I thought what you wanted was:
Create a new list, using:
<cfset list2 = "2,4,1,3,5">
- First, grab the item in position 2 (texttwo) ie texttwo
- Then add the item in position 4 (textfour) ie texttwo,textfour
- Then add the item in position 1 (textone) ie texttwo,textfour,textone
.. and so on...
No, I must be misunderstanding the logic you're trying to apply ;-) I thought what you wanted was:
Create a new list, using:
<cfset list2 = "2,4,1,3,5">
- First, grab the item in position 2 (texttwo) ie texttwo
- Then add the item in position 4 (textfour) ie texttwo,textfour
- Then add the item in position 1 (textone) ie texttwo,textfour,textone
.. and so on...
ASKER
No agx. What I have are items which have been selected and assigned an "order" number - Ie the order it should occupy in the total list of (in this example) 5.
textone has a ordering number of 2 and is locked to that number
texttwo has an ordering number of 4 and is locked to that number
etc
the routine should order the items as 5,4,3,2,1 and then decode that order by associating each number with its assigned item. So we get
XXX,texttwo,textfour,texto ne, textthree
================== ref===============
<cfset list1 = "textone,texttwo,textthree ,textfour, xxx">
<cfset list2 = "2,4,1,3,5"
textone has a ordering number of 2 and is locked to that number
texttwo has an ordering number of 4 and is locked to that number
etc
the routine should order the items as 5,4,3,2,1 and then decode that order by associating each number with its assigned item. So we get
XXX,texttwo,textfour,texto
================== ref===============
<cfset list1 = "textone,texttwo,textthree
<cfset list2 = "2,4,1,3,5"
If:
items = textone,texttwo,textthree, textfour,x xx
itemOrder = "2,4,1,3,5"
> the routine should order the items as 5,4,3,2,1
Does this refer to "items" or "itemOrder"? If items, what is a literal representation of 5,4,3,2,1?
items = textone,texttwo,textthree,
itemOrder = "2,4,1,3,5"
> the routine should order the items as 5,4,3,2,1
Does this refer to "items" or "itemOrder"? If items, what is a literal representation of 5,4,3,2,1?
ASKER
This refers to items. These items are textone, texttwo etc. The numbers give for each item the position that item should take in any printout. TEXTONE should occur in second 2 position, Texttwo should occur in fourth 4th position..... etc.
In practical terms, The user selects items from a long form listing.
After selecting each item he then enters into a text field ( immediately beside the checkbox used to select the item) a number. That number defines the positioning the chosen item should take in a printout of the total set of chosen items
On submitting the form to the action page, we have two lists - one giving the names of the items chosen and the other giving the ordering positions for each of the items.
Now we want to get a printout - a single column of rows with the names of the items. The printout is
xxx
texttwo
texxtfour
textone
textthree
or (and preferably ) the above is reverse order.
Thanks very much for persevering with this !
James
In practical terms, The user selects items from a long form listing.
After selecting each item he then enters into a text field ( immediately beside the checkbox used to select the item) a number. That number defines the positioning the chosen item should take in a printout of the total set of chosen items
On submitting the form to the action page, we have two lists - one giving the names of the items chosen and the other giving the ordering positions for each of the items.
Now we want to get a printout - a single column of rows with the names of the items. The printout is
xxx
texttwo
texxtfour
textone
textthree
or (and preferably ) the above is reverse order.
Thanks very much for persevering with this !
James
> the routine should order the items as 5,4,3,2,1
>>> If items, what is a literal representation of 5,4,3,2,1?
I think what may be confusing me is that you're giving the final results in reverse order, not the step before that :) I think the original code works, but the "reverse order" part adds another step. It's not as simple as just reversing the whole list. So I'm trying to understand that extra step, so I can figure out the modifications needed.
So given items " textone,texttwo,textthree, textfour,x xx", what's a literal representation of that intermediary step ie "5,4,3,2,1"?
>>> If items, what is a literal representation of 5,4,3,2,1?
I think what may be confusing me is that you're giving the final results in reverse order, not the step before that :) I think the original code works, but the "reverse order" part adds another step. It's not as simple as just reversing the whole list. So I'm trying to understand that extra step, so I can figure out the modifications needed.
So given items " textone,texttwo,textthree,
Yes, it is the extra "reverse" step that's the problem. Given the values:
<cfset items = "items = textone,texttwo,textthree, textfour,x xx">
<cfset itemOrder = "2,4,1,3,5">
The attached code should give you:
items = textone,texttwo,textthree, textfour,x xx
itemOrder = 2,4,1,3,5
newList = xxx,texttwo,textfour,texto ne,textthr ee
<cfset items = "items = textone,texttwo,textthree,
<cfset itemOrder = "2,4,1,3,5">
The attached code should give you:
items = textone,texttwo,textthree,
itemOrder = 2,4,1,3,5
newList = xxx,texttwo,textfour,texto
<cfset items = "text1,text2,text3,text4,xxx">
<cfset itemOrder = "2,4,1,3,5">
<!--- remove any non-numeric values --->
<cfset itemOrder = reReplace(itemOrder, "[^0-9,]", "", "all")>
<cfif listLen(items) eq listLen(itemOrder)>
<cfset newList = "">
<cfloop from="#listLen(itemOrder)#" to="1" index="revPos" step="-1">
<!--- NOTE: This will throw an error if #foundAt# is not a valid list position --->
<cfset foundAt = listFind(itemOrder, revPos)>
<cfset foundValue = listGetAt(items, foundAt)>
<cfset newList = listAppend(newList, foundValue)>
</cfloop>
<cfoutput>
items = #items#<br>
itemOrder = #itemOrder#<br>
newList = #newList#<br>
</cfoutput>
<cfelse>
ERROR: Unequal number of elements or invalid positions found
</cfif>
ASKER
Agx, that works nicely. Sorry for not getting back sooner, but my internet service was interrupted for several days.
If you have a final second, could you let me know how this line might be modified to reverse the order - which currently is 5,4,3,2,1. It would be better if it were 1,2,3,4,5
<cfloop from="#listLen(itemOrder)# " to="1" index="revPos" step="-1">
Many thanks again for your great help.
James
If you have a final second, could you let me know how this line might be modified to reverse the order - which currently is 5,4,3,2,1. It would be better if it were 1,2,3,4,5
<cfloop from="#listLen(itemOrder)#
Many thanks again for your great help.
James
I didn't test this, but I think changing the loop from descending to ascending order should do it. ie From 1 ...To 5 instead of From 5 ... To 1. You should probably change the variable name too. Since "rev[erse]Pos[ition]" no longer applies ;-)
<cfloop from="1" to="#listLen(itemOrder)#" index="revPos">
<cfloop from="1" to="#listLen(itemOrder)#" index="revPos">
ASKER
GREAT, just tested it and it works fine.
Cant tell you how much I appreciate your help !!
James
Cant tell you how much I appreciate your help !!
James
As always, you're very welcome!