UpdatePanel problem

Hi,

I have a modal popup, which has two listboxes in it and two buttons (Add and Remove). On pressing Add, a selected item is removed from the Source listbox and added to the Destination listbox, on pressing Remove, the selected item is removed from the Destination listbox and returned to the Source listbox.
I enclosed the above controls in UpdatePanel to avoid closing modal popup on pressing Add or Remove buttons. Probably, because of that UpdatePanel, I have troubles with handling the Remove button's pressing. Sometimes it works fine, but too often the selected item in the Destination listbox is said to be null (I see it when I do debugging), though it is actually selected.
Could anybody please help me deal with my problem?
Thanks.
tantormediaAsked:
Who is Participating?

[Product update] Infrastructure Analysis Tool is now available with Business Accounts.Learn More

x
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Umar Topia.Net Full Stack DeveloperCommented:
You have to use UpdateTriggers and put the Remove and Add button ids inside UpdateTriggers
0
tantormediaAuthor Commented:
Unfortunately, it doesn't help.
 Also, don't triggers include by default all child controls that invoke a postback?
0
Alfred A.Commented:
Hi,

Are you using sessions?  If you are, you might not be updating the values of the session once a remove is done in you destination listbox.   It is possible that you are not properly handling your sessions if you are using it.
0
Exploring SQL Server 2016: Fundamentals

Learn the fundamentals of Microsoft SQL Server, a relational database management system that stores and retrieves data when requested by other software applications.

tantormediaAuthor Commented:
Alfred,

I do use Sessions, but I don't know how it could affect ListBox's SelectedItem. Or maybe I don't understand something? Could you please clarify it for me?
Thanks.
protected void btnRemoveField_Click(object sender, EventArgs e)
    {
        List<string> sourceFields = new List<string>(dbColumns.Count);

        if (Session["SourceFields"] != null)
            sourceFields = Session["SourceFields"] as List<string>;

        sourceFields.Add(lstSelectedFields.SelectedItem.Text); // SELECTED ITEM HERE IS NULL!!!

        lstSourceFields.DataSource = sourceFields;
        lstSourceFields.DataBind();

        Session["SourceFields"] = sourceFields;

        List<string> selectedFields = new List<string>(dbColumns.Count);
        if (Session["SelectedFields"] != null)
            selectedFields = Session["SelectedFields"] as List<string>;

        selectedFields.Remove(lstSelectedFields.SelectedItem.Text);// SELECTED ITEM HERE IS NULL!!!

        lstSelectedFields.DataSource = selectedFields;
        lstSelectedFields.DataBind();

        Session["SelectedFields"] = selectedFields;
    }

Open in new window

0
Alfred A.Commented:
Can you also show us what is happening in your Add and Page_Load (if any)?

Add and Remove here are linked.  
0
tantormediaAuthor Commented:
Yes, here they are. I don't think Page_Load is relevant here.
        protected void btnSetSort_Click(object sender, EventArgs e)
    {
        // The Session items below are used only to save listboxes' state during working with SetSort modal popup. Without them, the state is lost because of UpdatePanel
        Session["SelectedFields"] = null;
        Session["SourceFields"] = null;

        List<string> sourceFields = new List<string>(dbColumns.Count);
        foreach (string field in dbColumns.Keys)
            sourceFields.Add(field);

        if (Session["OrderBy"] != null)
        {
            string strOrderBy = Session["OrderBy"] as string;
            string[] orderBy = strOrderBy.Split(',');
            lstSelectedFields.DataSource = orderBy;
            lstSelectedFields.DataBind();

            foreach (string selectedField in orderBy)
            {
                sourceFields.Remove(selectedField);
            }
            Session["SelectedFields"] = orderBy;
        }
        lstSourceFields.DataSource = sourceFields;
        lstSourceFields.DataBind();

        Session["SourceFields"] = sourceFields;

        OrderByModalPopupExtender.Show();
    }

protected void btnAddField_Click(object sender, EventArgs e)
    {
        List<string> selectedFields = new List<string>(dbColumns.Count); ;
        if (Session["SelectedFields"] != null)
            selectedFields = Session["SelectedFields"] as List<string>;

        selectedFields.Add(lstSourceFields.SelectedItem.Text);

        lstSelectedFields.DataSource = selectedFields;
        lstSelectedFields.DataBind();

        Session["SelectedFields"] = selectedFields;

        List<string> sourceFields = new List<string>(dbColumns.Count);
        if (Session["SourceFields"] != null)
            sourceFields = Session["SourceFields"] as List<string>;
        else
        {
            foreach(string field in dbColumns.Keys)
                sourceFields.Add(field);
        }

        sourceFields.Remove(lstSourceFields.SelectedItem.Text);

        lstSourceFields.DataSource = sourceFields;
        lstSourceFields.DataBind();

        Session["SourceFields"] = sourceFields;
    }

Open in new window

0
tantormediaAuthor Commented:
The strange thing is that btnAddField_Click() works.
0
Alfred A.Commented:
Hi,

I noticed something, lstSelectedFields, is this populated at the time when you click Remove button?  Can you try testing the count of lstSelectedFields something like lstSelectedFields.Items.Count
0
Alfred A.Commented:
Hi,

In doing this type of scenario, the Add and Remove should be synchronised.  The two should have the same code construct except the lstSelectedFields and lstSourceFields are reversed.

I noticed something, in Add, you have this

List<string> sourceFields = new List<string>(dbColumns.Count);
        if (Session["SourceFields"] != null)
            sourceFields = Session["SourceFields"] as List<string>;
        else
        {
            foreach(string field in dbColumns.Keys)
                sourceFields.Add(field);
        }

        sourceFields.Remove(lstSourceFields.SelectedItem.Text);


While in Remove, you have this,

List<string> selectedFields = new List<string>(dbColumns.Count);
        if (Session["SelectedFields"] != null)
            selectedFields = Session["SelectedFields"] as List<string>;

        selectedFields.Remove(lstSelectedFields.SelectedItem.Text);// SELECTED ITEM HERE IS NULL!!!


Try putting this in Remove,

else
        {
            foreach(string field in dbColumns.Keys)
                selectedFields.Add(field);
        }

Try to make the two functions, similar or synchronised.
0
tantormediaAuthor Commented:
No, dbColumns.Keys contains all possible items, and selectedFields contains only items previously selected from the SourceFields listbox and added to selectedFields.
In other words, the initial state for the SourceFields listbox is to have all possible items, and for the SelectedFields to be empty.
Besides that, I believe the methods have the same logic.
0
tantormediaAuthor Commented:
Answering your previous question, when the execution enters btnRemoveField_Click(), lstSelectedFields.Items.Count is shown to be 0 (which is not true).
An exception is thrown at
sourceFields.Add(lstSelectedFields.SelectedItem.Text);
because lstSelectedFields.SelectedItem is null.
0
Alfred A.Commented:
This is definitely weird.  If you can select items in lstSelectedFields, and then press Remove button, lstSelectedFields.Items.Count should at least be 1.

OK.  I have a suggestion.  Sort of an alternative approach, rather than putting the Generic List in a Session, why don't you put the ListBox themselves into the Sessions?

This would ensure that you have the actual state of the listboxes.
0
Alfred A.Commented:
Something like,

lstSelectedFields = Session["ListBoxSelected"] As ListBox;

and then work on it.  this would be the same as lstSourceFields.
0
tantormediaAuthor Commented:
Yes, but how will that help? I would then put in a Session the listbox with Items.Count = 0. Because this is what I have at the very beginning of btnRemoveField_Click().
0
Alfred A.Commented:
True, I actually agree with you, it is just the nature/weirdness of the situation.  It looks like it is not somehow maintaining the state of the listboxes.

Your solution, looking at it, should be okay but your lstSelectedFields.Item.Count is 0 even when there are items in it.

Putting them in session will test whether the state of the listboxes are really maintained or not.
0
dimitriInfoCommented:
Do you really need a UpdatePanel ? Because you can enclosed the control in a panel et use javascript to close the modal pop up adding an action on the two buttons.
0
tantormediaAuthor Commented:
dimitriInfo,

Could you give me more details on that, please?

Thanks.
0
tantormediaAuthor Commented:
Alfred, I did that test (putting the ListBox in a Session), and still got Items.Count = 0, as I expected.
0
Alfred A.Commented:
Ok.  At least that eliminates it.  

And yes, why do you need an UpdatePanel in the first place in the modal popup?

Or, is the UpdatePanel within the main page triggering the modal popup, right?
0
tantormediaAuthor Commented:
I need UpdatePanel because without it the popup was closing on pressing Add or Remove. And I want it to close only on Submit or Cancel.
0
Alfred A.Commented:
OK.  Before providing alternatives, do you have UpdateMode set to "Conditional"?
0
tantormediaAuthor Commented:
Yes, though first I tried without it.
0
Alfred A.Commented:
Oh yeah.  Now I remember, if any postback occurs, it will close it right away.

Check this out.

http://blogs.technet.com/kirtid/archive/2007/05/03/using-updatepanels-with-modalpopups.aspx


This whole problem might be the UpdatePanel not triggered properly.
0
tantormediaAuthor Commented:
If I understand correctly, the only scenario that corresponds to mine, is this:
ModalPopup with an UpdatePanel inside its Popup Panel: Make sure that the OK and Cancel buttons are not inside the UpdatePanel otherwise the handlers will be rendered useless on postback.

This condition is met. I don't see there anything else I could do.
Do you know how I can do without UpdatePanels at all?
0
Alfred A.Commented:
Well, you can try the following

if (Page.IsPostBack)
    {
        // reshow
        MyModalPopup.Show()
    }

in your main page, but this is ugly and would not quite solve your problem.
0
Alfred A.Commented:
You can also use a ConfirmButtonExtender if you want.  There are some limitation but you can try.

http://www.asp.net/ajax/ajaxcontroltoolkit/Samples/ConfirmButton/ConfirmButton.aspx

0
tantormediaAuthor Commented:
Alfred, how do you suggest I should use that ConfirmButton? I don't see any connection with my situation so far...
0
Alfred A.Commented:
0
tantormediaAuthor Commented:
First of all, I do use triggers after dimitriInfo's post above. But it didn't help. Plus, it is not needed, because explicit triggers should be used on controls beyond the UpdatePanel.
0
tantormediaAuthor Commented:
I still don't get how I can use ConfirmButton. How would it help?
0
Alfred A.Commented:
Anyway, going back to your Add and Remove, the question is why does it work fine in Add but not in Remove?

If Add works fine.  Remove should work fine.  They are both wrap in the UpdatePanel, right?
0
Alfred A.Commented:
Have you tried maybe testing Remove function by populating test selected  data and then start removing?
0
tantormediaAuthor Commented:
Yes, both Add and Remove are in UpdatePanel. I have no idea why they work differently.  
Moreover, even within the Remove handler, the SourceFields listbox contains data, but the SelectedFields listbox is empty.

Of cource, I first add several items and they try to remove them.
0
Alfred A.Commented:
What I meant is to put initial data on Selected Listbox and then try Remove.  If it works or not.

Isn't it your process is Add from Source first before doing any Remove at all?
0
tantormediaAuthor Commented:
OK, here is what I have done. I added some items from the Source listbox, and pressed Submit, thus saving the data in another Session[]. Then opened modal popup again, and the Selected listbox was populated with previously saved elements. Now I pressed Removed, and it works. How can it help us? I don't want to Submit intermediary results.
0
tantormediaAuthor Commented:
At least this explains why two listboxes behave differently: they are populated differently.
0
tantormediaAuthor Commented:
Though I still don't know why the SelectedFields listbox gets empty on Remove...
0
tantormediaAuthor Commented:
Actually, it doesn't get empty. It still contains item previously submitted. But the items just added by pressing Add are not in the listbox's Items.
0
tantormediaAuthor Commented:
I guess I will rather use JavaScript as what I have doesn't work...
Thank you for your time.
0
Alfred A.Commented:
Hi,

Out of curiosity, I created a project out of your posted code and during testing, both Add and Remove works fine!  The only adjustment I did was to use static values for the generic list index rather than using dbColumns.  I am posting what I tested in the code below.  By the way, I contained the popup in a user control (Sample.ascx).  


//Default.aspx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class _Default : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Button1_Click(object sender, EventArgs e)
        {
            mdlTest.Show();
        }
    }
}


//Default.aspx

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="WebApplication1._Default" %>
<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="ajaxToolkit" %>
<%@ Register src="Sample.ascx" tagname="Sample" tagprefix="uc1" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title></title>
</head>
<body>
    <form id="form1" runat="server">
     <asp:ScriptManager ID="ScriptManager1" runat="server">
    </asp:ScriptManager>
    <div>
        <asp:Button id="btnShowPopup" runat="server" style="display:none" />
          <ajaxToolKit:ModalPopupExtender
            ID="mdlTest" runat="server" TargetControlID="btnShowPopup" 
            PopupControlID="pnlPopup"
            RepositionMode="RepositionOnWindowResize" />
           <asp:Panel ID="pnlPopup" runat="server" Width="375px" style="display:none;">
              <asp:UpdatePanel ID="updPnlTest1" runat="server" 
                   UpdateMode="Conditional">
                <ContentTemplate>
                     <uc1:Sample ID="Sample1" runat="server" />
                </ContentTemplate>
              </asp:UpdatePanel>
          </asp:Panel>
        <asp:Button ID="Button1" runat="server" onclick="Button1_Click" Text="Button" />
    </div>
   
    </form>
</body>
</html>


//Sample.ascx.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;

namespace WebApplication1
{
    public partial class Sample : System.Web.UI.UserControl
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                Session["SelectedFields"] = null;
                Session["SourceFields"] = null;
                List<string> sourceFields = new List<string>(3);
                sourceFields.Add("Test1");
                sourceFields.Add("Test2");
                sourceFields.Add("Test3");
                lstSourceFields.DataSource = sourceFields;
                lstSourceFields.DataBind();
                Session["SourceFields"] = sourceFields;
            }

        }

        protected void btnRemoveField_Click(object sender, EventArgs e)
        {
            List<string> sourceFields = new List<string>(3);

            if (Session["SourceFields"] != null)
                sourceFields = Session["SourceFields"] as List<string>;

            sourceFields.Add(lstSelectedFields.SelectedItem.Text); // SELECTED ITEM HERE IS NULL!!!

            lstSourceFields.DataSource = sourceFields;
            lstSourceFields.DataBind();

            Session["SourceFields"] = sourceFields;

            List<string> selectedFields = new List<string>(3);
            if (Session["SelectedFields"] != null)
                selectedFields = Session["SelectedFields"] as List<string>;

            selectedFields.Remove(lstSelectedFields.SelectedItem.Text);// SELECTED ITEM HERE IS NULL!!!

            lstSelectedFields.DataSource = selectedFields;
            lstSelectedFields.DataBind();

            Session["SelectedFields"] = selectedFields;

        }

        protected void btnAddField_Click(object sender, EventArgs e)
        {
            List<string> selectedFields = new List<string>(3); ;
            if (Session["SelectedFields"] != null)
                selectedFields = Session["SelectedFields"] as List<string>;

            selectedFields.Add(lstSourceFields.SelectedItem.Text);

            lstSelectedFields.DataSource = selectedFields;
            lstSelectedFields.DataBind();

            Session["SelectedFields"] = selectedFields;

            List<string> sourceFields = new List<string>(3);
            if (Session["SourceFields"] != null)
                sourceFields = Session["SourceFields"] as List<string>;
            else
            {
                //foreach (string field in dbColumns.Keys)
                //    sourceFields.Add(field);
            }

            sourceFields.Remove(lstSourceFields.SelectedItem.Text);

            lstSourceFields.DataSource = sourceFields;
            lstSourceFields.DataBind();

            Session["SourceFields"] = sourceFields;

        }

       
    }
}


//Sample.ascx

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="Sample.ascx.cs" Inherits="WebApplication1.Sample" %>
<asp:UpdatePanel ID="updPnl1" runat="server" 
                   UpdateMode="Conditional">
                <ContentTemplate>
                    <asp:ListBox ID="lstSourceFields" runat="server"></asp:ListBox>
<asp:ListBox ID="lstSelectedFields" runat="server"></asp:ListBox>
<asp:Button ID="btnAddField" runat="server" onclick="btnAddField_Click" Text="Add" />
<asp:Button ID="btnRemoveField" runat="server" onclick="btnRemoveField_Click" 
    Text="Remove" />
                </ContentTemplate>
              </asp:UpdatePanel>

Open in new window

0
tantormediaAuthor Commented:
I don't know what to say. There must be wrong about my project. It is not the only weird thing that happens...
0
Alfred A.Commented:
Hi,

Can you try the code I posted if it works in your IDE?  It only consist of default.aspx, default.aspx.cs, sample.ascx, and sample.ascx.cs.  

Also, I used VS2008.
0
Alfred A.Commented:
Oh, by the way, I also use AjaxToolKit release 3.0.30930.2
0
tantormediaAuthor Commented:
Did you try it in IE or FireFox?
Because some problems that I had in Firefox disappear in IE.
0
Alfred A.Commented:
I tested it IE (6/7/8) in my office test machines before.  I just finish testing it using Firefox 3.6.3 and it works just fine playing with Add and Remove back and forth.  
0
Alfred A.Commented:
Oh, and another thing, just note that I did not use your dbColumns because I just want to see first if the session process is working fine.  If my posted code really works, then there must be something wrong with the way dbColumn is use.  Also, note that I removed sorting as well to slowly eliminate the issues.

This might be just coding construct issues in the end.
0
tantormediaAuthor Commented:
I don't know why it gives me error:
error CS0103: The name 'mdlTest' does not exist in the current context
0
Alfred A.Commented:
By the way, I just use the default web application project name "WebApplication1" in the project that I built.

The namespaces of the default.aspx.cs and sample.ascx.cs should be "WebApplicaton1".

Or, change the namespaces to the name of your hosting project.

0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
tantormediaAuthor Commented:
I just copied your code thoroughly.
0
Alfred A.Commented:
If you go to IDE menu Project -> Properties and then Application tab area, you should see there what is your default namespace.
0
tantormediaAuthor Commented:
Yes, this project works. It is probably my tough luck...
0
Alfred A.Commented:
OK.  Can you now try to incorporate if possible the additional elements (i.e. dbColumns and Sorting) in this working project and then try it again?

At least, at this level, we know that the updatepanel and session processes are working.
0
tantormediaAuthor Commented:
Hi Alfred,

Sorry for the delay. I used dbColumns, and though the debugging shows that lstSelectedFields contains items in it, the listbox doesn't show up.
Plus also, in
            if (Session["SourceFields"] != null)
                sourceFields = Session["SourceFields"] as List<string>;

though the second line is executed, and Session["SourceFields"] contains 27 elements, the sourceFields stays null. I don't know what to think. It is not that urgent now, as I implemented it in javascript.
0
Alfred A.Commented:
Hi,

If you found another solution, then that is good to hear.  Anyway, goodluck with your projects. :-)
0
tantormediaAuthor Commented:
Thanks Alfred,

I appreciate your effort and dedication to help.
0
tantormediaAuthor Commented:
Thank you for doing your best to help.
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
ASP.NET

From novice to tech pro — start learning today.