Link to home
Start Free TrialLog in
Avatar of Starr Duskk
Starr DuskkFlag for United States of America

asked on

Retrieving ListBox selected data client side failing

I'm using asp.net 4.5 framework.
I am trying to use a listboxFrom and a listboxTo client side, and then save the values of the listboxTo server side.

Here is an example:

       function fnMoveAll(lstFrom, lstTo, type) {

            var varFromBox = document.all(lstFrom); var varToBox = document.all(lstTo);


    if ((varFromBox != null) && (varToBox != null)) {

        if (varFromBox.length < 1) {

            alert('There are no items in the source ListBox');

            return false;
        }

        while (varFromBox.length >= 0) {

            var newOption = new Option(); // Create a new instance of ListItem

            newOption.text = varFromBox.options[0].text;

            newOption.value = varFromBox.options[0].value;

            varToBox.options[varToBox.length] = newOption; //Append the item in Target Listbox

            varFromBox.remove(varFromBox.options[0]); //Remove the item from Source Listbox

        }
    }
    return false;
}

Open in new window


The client side moving is working perfectly.

However, when I press the SAVE button and loop through the selected values, it only recognizes the list values of what it was originally. It doesn't have the values I added client side:

For Each listItemVal As ListItem In lstSelected.Items
                selectedId = listItemVal.Value
                '  do stuff
            Next

Open in new window


What am I doing wrong that the client side changes are not recognized server side?

listboxes are defined like so:
                        <asp:ListBox runat="server" CssClass="stylListBox stylScrollbar" ID="lstAvailable" ClientIDMode="Static" SelectionMode="Multiple"></asp:ListBox>

Open in new window


Thanks!
Avatar of Chinmay Patel
Chinmay Patel
Flag of India image

Hi Starr,

This is by design. You can overcome it but then you should be careful with that approach.
And before we get to the solution are you using UpdatePanel control?

Regards,
Chinmay.
Avatar of Starr Duskk

ASKER

I fixed it. on my button submit i run a javascript function to loop through the tobox and store the values into a hidden field. then it does the server side submit and retrieves the hidden field values and loops through them like it would a normal listbox postback event.

thanks!
Hi Starr,

As you are well aware ASP.Net by design uses ViewState to transfer controls of the states(their values, selected values, options etc) between the server and client. What you are asking ... violates that security mechanism (even though it is something that we wish to do due to business requirements) and hence whatever option I want to suggest, I want to be cautious with my approach.

Also if you are saying you have large number of dropdowns and they have large number of options then entire viewstate will be HUGE to manage. I strongly recommend using AJAX in such scenarios i.e. only do a complete page postback when you need to.

Would you like to run some couple of hacks before we come to a concrete solution? And before I post some code, would you be ok to use AJAX in this project?

PS: I wrote the above comment :P then I slept.. in case you would want to look at other approaches, do let me know.

Regards,
Chinmay.
21 hours ago I closed this with my solution. 8 hours ago you wrote further questions. I don't wish you to waste any further time on this as I have already created a javascript solution to retrieve the data.

thanks!
Yes... I am not asking to open the question or assigning points :) I was just saying, I wrote that comment and thought I'd post it but I didn't and went to bed... in the morning I realized I didn't post it but thought if you still would like to see some solution around it but you are right, if it is working already, we should not invest more time after it.
Chinmay,

I get it. I can write up a new ticket and get further info on your solution because I'm interested...
currently when we move stuff, it is quick because it's client side.

but when we save it, and hit the page load, it displays on the screen with the stuff back the way it was when the page initially  loaded, I'm assuming that's because of the ViewState reloading. Then of course we also run javascript to save the list on the right to a hidden field and then save the hidden field values on the same button click on postback. So the button hits the clients side, populates the hidden field, and then does the server side post back to retrieve and save.

the ugly thing is that the screen appears to refresh back to the old state and we'd like to have it NOT do that.

If your solution has some way of avoiding that, and keeping the clientside moving ability (yes, we've done the server side move and it's sloow) then I'll write a new ticket to open that discussion.

thanks!
No need to create a new one. Let me see what I can do, I was thinking to implement something that will affect both client and server side at the same time. but as I said, I am not sure if it will work or not. But yes I wanted to know if you'd like to something on those lines that's why I asked. I will update this thread once I find something positive.
So you don't waste time showing me how to do something I already have, I currently have a button that populates a hidden field with the listbox values:

btnSave.OnClientClick = "return populateHiddenFromListBox('lstSelected','hdnListBoxTo');"

It always returns true to do the postback after the javascript is done.

Then I retrieve the list from the hidden field:
Dim buildSelectedList As String = hdnListBoxTo.Value

I do my deletion of those no longer in the list and then loop through and insert the ones that are new:

            If buildSelectedList IsNot Nothing Then
                If Not buildSelectedList.Equals(String.Empty) Then
                    For Each id As String In buildSelectedList.Split(CChar(","))
                        InsertIfNotExists(CInt(id))
                    Next
                End If
            End If

Open in new window


After it saves, I have a popup that says "Changes Saved"

During this time, you can see in the background the list going back to the way it was before I made any client side changes. Then after 1 second, I refresh the page so that it reloads with the list the way it should be.

So right now, the only thing is getting that list to not show the old way. We tried making the background behind the save popup black, but it still shows before it turns black.

Thanks!
Please post the entire codebehind, aspx along with the JavaScript. You can remove sensitive information, but leave the code that participates in current issue OR create a sample page, reproduce your scenario with only 1 dropdown and post the code here using code tags.
Attached is a runable aspx page and js file.

I have two submit buttons: the one on the left submits using the javascript and a hidden field. It shows how the page resets back to the way it was.

The right button submits using the move buttons on the right, which issue a postback and saves in codebehind. It does retain the proper values on the screen. But for large lists is very slow.

Thanks!

well, that bites. It doesn't accept my zip file because it doesn't like my file extensions. Let me see what are acceptable file names and try again.

change the aspx.xx to aspx.vb
ListBoxSelect.zip
ASKER CERTIFIED SOLUTION
Avatar of Chinmay Patel
Chinmay Patel
Flag of India image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Thank you! We'll take a look. Right now we're putting out another fire elsewhere, so I'll get back to this as soon as that is over. Thanks!
No worries. This is just a PoC, take your time.
Chinmay,

I think I got everything converted to vb.net properly, but the arrow buttons to move the list values doesn't seem to be triggering at all.

I tried putting a path in, but that didn't trigger the click either. it just doesn't seem to ever hit the javascript code. Here is my runnable version in the zip. Just change the .xx to .vb.

I did try with the javascript within the code in front, that didn't trigger it either, so I put it into a .js file hoping... still not triggering.

Please take a look.

thanks!
Starr
ListboxMagicVB.zip
Any suggestions Chinmay?
Couple of questions

1. Did you put alert boxes or debugger; statement in your JS to see, if it is actually being called?
2. Why the explicit URLs - PassUrls? I was thinking these pages are of the same app. If that's not the case, this method will not work.
3. Did you enable PageMethods/WedMethods in the script manager?

Any web development that we do, especially tricky ones, require us to debug JavaScript as well.

PS: Please post your code using Code tags. I have very recently faced a very bad incident, I am sorry but I will not be downloading Zip files from now on. You can post as much code as you want using Code tags. I will go through it but not zip files. I hope you would understand.
As I said, I tried putting a path in to see if that would help. Buit I also tried without.

I'll look at some of the other things as well.

And ScriptManager seems to be missing entirely. :)

That's probably it! I usually use master pages with all that already set up.

Thanks!
Update... saw that these methods need to be shared and added the responseformat.

   <WebMethod()>
    <ScriptMethod(ResponseFormat:=ResponseFormat.Json)>
    Public Shared Sub MoveFromL2toL1(ByVal ids As String())

Open in new window


So code is now hitting them.

Also saw this in another person's example, so thinking I might need it:
jquery-3.2.1.min.js

Probably was in your master page?

Update to come.
by george I think I've got it!

thanks for all your help!
:D... but I think we are not there yet. Have you replaced your all other Dropdowns with this code? Did you observe performance improvements - If I go by your word - earlier there was a significant delay in page loads?
yes, doing it all from code behind was tediously slow. I got the example page to work, but I am in the process of reproducing that code on my live page using the real database. So no, I haven't yet completed it but am fairly sure I can get it to work. I will then write it up as a class library to be shared by all listboxes in the system and pass in the session name, etc.

If I have problems with any of that, I will write up a new ticket with the specific issue I am having on the live page and library.

Thanks!
Cool. That's what I am more interested in. I will wait for your update. All the best.
Chinmay,

I'm having a problem with this part of your code:

        [WebMethod(true)]
        [ScriptMethod]
        Public Static void MoveFromL1toL2(String[] ids)
        {
            String[] currentValue = HttpContext.Current.Session["L1toL2"] As String[];
            If (currentValue!= null)
            {
                currentValue.ToList<string>().AddRange(ids.ToList<string>());
            }
            Else
            {
                HttpContext.Current.Session.Add("L1toL2", ids);
            }
        }

Open in new window


if it's not null, isn't it missing the part where you add the value back to the session? Because it fails when I send values one at a time to the right list. like select > move over, select another > move over. And then I stepped through and noticed it's not saving to the session again.

thanks!
I'm going to try this:
    Public Shared Sub MoveFromL1toL2(ByVal ids As String())

        Try
            Dim currentValue As String() = HttpContext.Current.Session("L1toL2")
            If Not currentValue Is Nothing Then
                Dim newval As String() = currentValue.Concat(ids)
                HttpContext.Current.Session.Add("L1toL2", newval)

Open in new window

well, that didn't work. I'm going to write up a new question
I figured it out. I added a strongly typed session and then added it and used .ToArray()

            Dim currentValue As String() = SiteSessions.ListboxMagicRightToLeft()
            If Not currentValue Is Nothing Then
                ' if it's not empty add the ids to what's already in there
                ' this situation occurs if the user selects a value from the list, moves it over
                ' then selects another value and moves it over, all before saving the first value
                Dim newval As String() = currentValue.Concat(ids).ToArray()
                ' store both values again back to the session
                SiteSessions.ListboxMagicRightToLeft() = newval

Open in new window