tags:

views:

175

answers:

2

Preface: First time really using JavaScript + jQuery, so my problem likely stems from a lack of understanding.

I have some very simple Javascript to move elements from one ListBox to another:

$('[id$=AddRole]').click(function () {
  $('[id$=MissingRoles] option:selected').appendTo('[id$=Roles]');
  return false;
});

$('[id$=RemoveRole]').click(function () {
  $('[id$=Roles] option:selected').appendTo('[id$=MissingRoles]');
  return false;
});

This works wonderfully - when I click a button, the items in one list move to the other as you would expect. Fantastic! A button is then clicked forcing a Postback. In the if (IsPostBack) section of my code, I extract the 'Roles' ItemCollection and print each item out, assuming to see any new items I added. Sadly, I only get the original items that were DataBound to the list. I don't have my DataBind accidently in the IsPostBack section, so I know I'm not simply re-binding.

I'm assuming I'm missing a step here. Is there something I need to do to tell .NET to actually update the contents of the ListBox? Guessing that whatever jQuery is doing is purely aesthetic, but I'm at a loss on how to commit its changes to my controls.

+1  A: 

This is actually a limitation that is due to the fact that .NET assumes that everything is left the way it was first served. If the site renders a textbox, it'll know that the value may have changed, and it updates its value based on the POST data. If it renders a disabled textbox, for instance, it "knows" that the value cannot have changed, and so, you will not be able to get the changed text, even if a javascript has enabled the textbox.

The same thing is happening here. .NET assumes it already knows what items belong to which list. The selected value is always being posted in the Request.Form collection, so even if the values in the .NET listbox control doesn't change, you will still be able to fetch the values that way (Request.Form[myListBox.ClientID]), but the values that are not selected in any of the listbox, are not being passed as form data, so there is actually technically no way for the server to know in which ways you tampered with the listbox before submitting it.

What you have to do isn't very pretty, but it's the only way. In both of your functions that move data around, you'll have to make sure that they also update a hidden field. It could be one hidden field for each listbox, or one hidden field containing the comma separated values of all listbox items, in a pipe-separated list of all listboxes, or whichever way you want to represent the data, but at the end of the day, you really have to manually make a string representaiton of the data in the different listboxes, that you can pick up at the serverside, and use to re-bind your listboxes with the new, relevant data.

David Hedlund
Thank you for the clarification. I'll have to bookmark this for future frustrations. I'll likely end up doing what Mark suggested, as this was what I was originally intending on.
abx1947
i must say i emphatically don't recommend that, although that is, of course, very much your own choice. i consider updatepanels an absolute abomination. are you aware that ajax.net is not actually asynchronous at all? and what's worse, the whole page is actually rendered, altho just the relevant part of it is being sent back. you also have to pass the whole viewstate, which could be *heaps* more than the current operation demands. and, worst of all, you'd have to make a server call for every change, rather than just passing the information in the postback that would occur anyway.
David Hedlund
A: 

If you are using asp.net I believe this is because you are not manipulating the viewstate, and this is important to the asp.net server on the postback to render.

I would suggest simply using an UpdatePanel to wrap your controls. Asp.net has great Ajax type functionality built in already, no full postback necessary. Their logic controls all the name mangling and viewstate.

Mark Kadlec
The ironic part is, I wanted to use jQuery because UpdatePanels were a bit slow for me in the past - figured this time I'd use less overhead and go right to a powerful library. Guess not! I'll do as you suggested, as I am already familiar with how that works.
abx1947
I know the overhead involved, but I've actually had really good performance results with the UpdatePanels, just position them wisely.JQuery would normally be a great fit for something like this, but I would strongly recommend against using it here because the hidden field approach would be kludgy and developers looking at your code in the future will have fits.
Mark Kadlec