Duplicate List Items

9 posts, 0 answers
  1. Panther
    Panther avatar
    6 posts
    Member since:
    Jun 2010

    Posted 06 Jul 2010 Link to this post

    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();  
        }  
    }  
  2. Genady Sergeev
    Admin
    Genady Sergeev avatar
    1596 posts

    Posted 07 Jul 2010 Link to this post

    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
  3. UI for ASP.NET Ajax is Ready for VS 2017
  4. Panther
    Panther avatar
    6 posts
    Member since:
    Jun 2010

    Posted 07 Jul 2010 Link to this post

    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();  
        } 


  5. Genady Sergeev
    Admin
    Genady Sergeev avatar
    1596 posts

    Posted 09 Jul 2010 Link to this post

    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
  6. Panther
    Panther avatar
    6 posts
    Member since:
    Jun 2010

    Posted 09 Jul 2010 Link to this post

    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.
  7. Genady Sergeev
    Admin
    Genady Sergeev avatar
    1596 posts

    Posted 15 Jul 2010 Link to this post

    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
  8. Panther
    Panther avatar
    6 posts
    Member since:
    Jun 2010

    Posted 15 Jul 2010 Link to this post

    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
  9. Scott Hannon
    Scott Hannon avatar
    18 posts
    Member since:
    Dec 2008

    Posted 08 Feb 2011 Link to this post

    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
  10. Anjali
    Anjali avatar
    101 posts
    Member since:
    Dec 2010

    Posted 03 Oct 2011 Link to this post

    I am having the same duplicate problem in my listbox. Was anyone able to solve it.
Back to Top
UI for ASP.NET Ajax is Ready for VS 2017