This is a migrated thread and some comments may be shown as answers.

Duplicate List Items

8 Answers 376 Views
ListBox
This is a migrated thread and some comments may be shown as answers.
Panther
Top achievements
Rank 1
Panther asked on 06 Jul 2010, 08:24 PM
I am having a problem with duplicate items in my listbox. I am using a RadListBox and a RadGrid. Each row in the grid has a checkbox and when the box is checked that item is added to the listbox with javascript (below.) After the user is done checking boxes they click a submit button and I am able to read the items from the list in the server side event handler.

The problem happens when the user changes pages on the grid. If they check 1 box from the first page and then go to the second page, the listbox will correctly show 1 item, but on the server side there will be 2 in the .Items collection. I added a breakpoint to the PreRender handler and found that the duplicate wasn't there yet. It is added after all the page is loaded, but I also added an alert box to the js below and it never fires on the second page of the grid. I can't figure out where the duplicate is coming from.

Any idea what's causing this?

function CheckChanged(sender, invoiceNumber) {  
    var listbox = $find("<%=lstInvoiceNoteEntry.ClientID %>");  
    if (sender.checked) {  
        var item = new Telerik.Web.UI.RadListBoxItem();  
        item.set_text(invoiceNumber);  
        listbox.trackChanges();  
        listbox.get_items().add(item);  
        listbox.commitChanges();  
    }  
    else {  
        var item = listbox.findItemByText(invoiceNumber);  
        listbox.trackChanges();  
        while (item) {  
            listbox.get_items().remove(item);  
            item = listbox.findItemByText(invoiceNumber);  
        }  
        listbox.commitChanges();  
    }  
}  

8 Answers, 1 is accepted

Sort by
0
Genady Sergeev
Telerik team
answered on 07 Jul 2010, 12:21 PM
Hi Ryan,

Can you please paste here your markup and any relevant code-behind code so that we receive better understanding of your scenario. Is the listbox inside edit form ? Keep in mind that the paging causes postback, hence RadListBox will "play" its log and add the client-side added items to the server-side collection. Thank you.

All the best,
Genady Sergeev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Panther
Top achievements
Rank 1
answered on 07 Jul 2010, 01:37 PM
The ListBox is not in edit mode. Notes and Invoices have a one-to-many relationship so we want to submit a note and reference multiple invoices.

Thanks for your help!

Here is the relevant markup:
<telerik:RadGrid   
    ID="RadOpenInvoicesGrid"   
    runat="server" 
    AllowPaging="True"   
    AllowSorting="True" 
    GridLines="None"   
    Skin="Default"   
    Width="100%" 
    OnItemDataBound="RadOpenInvoicesGrid_ItemDataBound"   
    OnItemCommand="RadOpenInvoicesGrid_ItemCommand" 
    AllowFilteringByColumn="true"   
    ShowFooter="true">  
    <MasterTableView CssClass="copysmall" 
        AutoGenerateColumns="False"   
        DataKeyNames="InvoiceNo" GridLines="None">      
        <FooterStyle BackColor="#9D9C9C" ForeColor="White" Font-Bold="true"></FooterStyle>              
        <Columns> 
            <telerik:GridTemplateColumn   
                AllowFiltering="false"   
                UniqueName="Add"   
                SortExpression="Add"   
                HeaderText="Add"   
                HeaderStyle-Width="10px">  
                <ItemTemplate> 
                    <asp:CheckBox ID="cbAdd" runat="server" onclick='<%# DataBinder.Eval(Container.DataItem, "InvoiceNo", "CheckChanged(this,{0});") %>' /> 
                </ItemTemplate> 
            </telerik:GridTemplateColumn> 
            <telerik:GridBoundColumn />                                                      
            <telerik:GridBoundColumn />           
            <telerik:GridBoundColumn />   
            <telerik:GridTemplateColumn /> 
            <telerik:GridNumericColumn /> 
            <telerik:GridNumericColumn /> 
            <telerik:GridBoundColumn /> 
            <telerik:GridBoundColumn /> 
        </Columns>                                              
    </MasterTableView> 
</telerik:RadGrid> 
 
<asp:UpdatePanel ID="InvoiceListBoxUpdatePanel" runat="server" UpdateMode="Conditional">  
    <ContentTemplate>                                     
        <telerik:RadListBox ID="lstInvoiceNoteEntry"   
            runat="server" Height="100px"   
            AllowReorder="false"   
            AllowDelete="false">  
        </telerik:RadListBox> 
    </ContentTemplate> 
</asp:UpdatePanel> 
 
 

And the codebehind stuff:
 
    protected void RadOpenInvoicesGrid_ItemDataBound(object sender, GridItemEventArgs e)  
    {  
        try 
        {  
            if (e.Item is GridDataItem)  
            {  
                GridDataItem item = (GridDataItem)e.Item;  
                CheckBox box = (CheckBox)item.FindControl("cbAdd");  
                TableCell myCell_InvoiceNumber = item["InvoiceNo"];  
 
                //If in Listbox, check the box next to the correct Invoice Number  
                foreach (RadListBoxItem tListItem in lstInvoiceNoteEntry.Items)  
                {  
                    if (tListItem.Value == myCell_InvoiceNumber.Text)  
                    {  
                        //Check the Checkbox  
                        box.Checked = true;  
                    }  
                }  
            }  
        }  
        catch (Exception ex)  
        {  
            lblErrorMessage.Text = ex.Message;  
        }  
    }  
 
protected void RadOpenInvoicesGrid_ItemCommand(object sender, GridCommandEventArgs e)  
    {  
        if (e.CommandName == "Filter" || e.CommandName == "Page" || e.CommandName == "Sort" || e.CommandName == "ChangePageSize")  
        {  
         if (DataObject.InvoiceCol.HasValue())  
          {  
            RadOpenInvoicesGrid.DataSource = DataObject.InvoiceCol;  
            RadOpenInvoicesGrid.DataBind();  
 
            //Update the Update Panel so it shows it open or closed  
            InvoiceUpdatePanel.Update();  
          }  
        }  
    }  
 
 
    protected void btnSave_Click(object sender, EventArgs e)  
    {  
        InvoiceNoteType cint = new InvoiceNoteType();  
        cint.InvoiceRefCol = new InvoiceNoteType.InvoiceRefColType();  
        foreach (RadListBoxItem rlbi in lstInvoiceNoteEntry.Items)  
        {  
            // This is my current workaround for the issue  
            if (!cint.InvoiceRefCol.Contains(rlbi.Value))  
            {  
                cint.InvoiceRefCol.Add(rlbi.Value);  
            }  
        }  
 
        //Add Note To Collection  
        DataObject.InvoiceNoteCol.Add(cint);  
 
        //Pass DataObject and get back updated DataObject  
        DataObject = Wrapper.Provider.Submit(Context, DataObject);  
 
        NoteEntryUpdatePanel.Update();  
    } 


0
Genady Sergeev
Telerik team
answered on 09 Jul 2010, 03:23 PM
Hi Ryan,

I believe that the problem comes from the following method:

if (e.CommandName == "Filter" || e.CommandName == "Page" || e.CommandName == "Sort" || e.CommandName == "ChangePageSize"
        
         if (DataObject.InvoiceCol.HasValue()) 
          
            RadOpenInvoicesGrid.DataSource = DataObject.InvoiceCol; 
            RadOpenInvoicesGrid.DataBind(); 
  
            //Update the Update Panel so it shows it open or closed 
            InvoiceUpdatePanel.Update(); 
          
        }

You should not call the InvoiceUpdatePanel.Update() method when the commant is Page. RadListBox plays the log and inserts the items on every postback. When the Update() method is called, the changes will  be reflected to the client as well. Otherwise, they are going to be lost until a postback that actually targets to update the ListBox, which I believe, is what you target.

Greetings,
Genady Sergeev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Panther
Top achievements
Rank 1
answered on 09 Jul 2010, 06:04 PM
Thanks for getting back to me. I tried removing the Update() call, but it is still duplicating the list items.

For example If I check one box one the first page and then check the first box on the second page, the listbox will have 3 items in its .Items collection. If I continue to the third page and check the first box it will have 6 items in its .Items collection. Although it still shows the correct number in the UI.
0
Genady Sergeev
Telerik team
answered on 15 Jul 2010, 01:44 PM
Hello Ryan,

The problem here is that the RadListBox plays its log on every postback. So, the items added on the client are inevitably added to the controls collection as the RadListBox is posted. I think, that a possible solution is to remove the last added items if the posttback was caused by 'Page'. Here is some pseudo code that does this:

private int originalItemsCount;
 
    protected void Page_Init(object sender, EventArgs e)
    {
        originalItemsCount = RadListBox1.Items.Count;
    }
 
   
    void GridItemCommand
    {
        if(ItemCommand Is 'Page') {
        'var itemsToBeRemoved = RadListBox1.Items.Where(i => i.Index >= originalItemsCount).ToArray();
 
        foreach (RadListBoxItem item in itemsToBeRemoved)
        {
            RadListBox1.Items.Remove(item);
        }
        }
    }

For convenience I've prepared sample project that shows how to remove the last items added  on the client. You can find it as an attachment.

Regards,
Genady Sergeev
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Panther
Top achievements
Rank 1
answered on 15 Jul 2010, 08:48 PM
Thanks for all of your help Genady. I wasn't able to get it to work by removing the last items as you suggest. In the page_init the originalitemscount was always 0. I did find that if I removed the updatepanel around my grid as well as the call to the Update method it keeps the correct number of items in the listbox. Unfortunately we need to keep the updatepanel there so the fix we have in place will have to suffice.

Thanks again!

Ryan
0
Scott Hannon
Top achievements
Rank 1
answered on 08 Feb 2011, 08:43 PM
I was having the same problem. The simple way I solved it was to add the RadListBox as an updated control in AjaxManager for every value-changeable control on the page, including itself. This way, no matter what else was done first, the listbox control only "played its client log" one time.
This may or may not fit your situation.
Scott
0
Anjali
Top achievements
Rank 1
answered on 03 Oct 2011, 06:54 PM
I am having the same duplicate problem in my listbox. Was anyone able to solve it.
Tags
ListBox
Asked by
Panther
Top achievements
Rank 1
Answers by
Genady Sergeev
Telerik team
Panther
Top achievements
Rank 1
Scott Hannon
Top achievements
Rank 1
Anjali
Top achievements
Rank 1
Share this question
or