I was finishing up development for a project we are wrapping up today and one of the last things I was working on was a fairly simple administrative page (so I thought!).
On this page I had two lists of documents that are associated with a product. The goal of the page is to indicate which of the associated documents are to be displayed on the product's detail page and in what order they are to be displayed. The first list displayed those shown on the detail page and the second list displayed those not shown on the detail page. The lists were done with repeaters. It would have made things a lot easier if it had been done with a datagrid, but all the other administrative layouts were done with repeaters and I couldn't really get the same look that we wanted with a datagrid. The lists are fairly short (3 or 4 items in each list) and we didn't need sorting, paging, etc.
To move the items between the two lists, I simply added a “remove” or “add” button, depending on the case, that used the onItemCommand to pass in the ID of the item, did the update, and then redisplayed the list. Pretty simple stuff.
The tough part was allowing changing of the ordering of those documents, though. Because there was so much admin-defined ordering throughout the site, we chose to use a simple system of relative priority ordering, where everything was assigned a value of 0 to 99. Items with 0 displayed first, 99 last, you get the picture. This was easily implemented with a simple dropdown list in all the other pages.
I figured that the best way to make it work in this case was to do the same, display the dropdown list in one of the columns of each row of the repeaters with the proper value being pre-selected. I would make the dropdowns autopostback and have a subroutine that updated the item's order and then refresh the lists (so the items would be moved around to their new proper places). Doing so proved to be a little work. After a bunch of trial and error and some google searches which proved useless, I finally implemented assigning text/values and setting the selected value in the ItemDataBound event handler. I was able to fill the list with values from 0 to 99 and made the selected value the item's “order“ DataItem.
So far so good - I had all the values displaying properly. Getting the onSelectedIndexChanged to fire correctly (because the dropdownlists were buried inside the repeater) and passing in 2 values proved to be hard work. I needed two values, the new “order“ value and the “id“ of the item being updated. Once again I turned to google and found not much help. After trying to access the DataItem for the RepeaterItem through the sender.parent proved fruitless I had to try another option. I'm not sure yet why this didn't work, I don't know if you can't do it for a repeater (the example I found used a datagrid and seemed to work) or if it had something to do with my “late binding“ of the data through the ItemDataBound event. I was able to access the RepeaterItem, but I couldn't get its DataItem properties. I will have to look into this further later. Regardless, it didn't work.
I eventually decided to implement a hashtable when I was adding my data in the ItemDataBound handler. I added the “UniqueID“ for the dropdownlist as the key (because the uniqueID has already been assigned at the point of ItemDataBound) and my “id“ field for the document as the value. Then when triggering my onSelectedIndexChanged all I had to do was lookup the hash for the unique id of the dropdownlist, which returned the “id“ of the row. So I now had both parts I needed, the new order value selected in the dropdownlist and the id of the document. After that I just needed to run a simple sql statement and refresh my two repeaters.
Wow. Seems like a lot of work for something seemingly so simple. Maybe next time I'll just use a datagrid :)