Duplicate ClientIds with EnableAutomaticLoadOnDemand

6 posts, 1 answers
  1. Mammu
    Mammu avatar
    9 posts
    Member since:
    Jan 2010

    Posted 08 Mar 2011 Link to this post

    Hi All,

    I have created a custom template which contains a checkbox and a label for the RadComboBox multi select capability. When I enable AutomaticLoadOnDemand property to true, for the first request the markup is generated for first 10 items and for consecutive requests the checkbox client id's are same as the checkboxes that were requested for the first time. Is there anyway I can maintain the different id's for checkbox controls?

    Thanks in advance!!!
  2. Mammu
    Mammu avatar
    9 posts
    Member since:
    Jan 2010

    Posted 10 Mar 2011 Link to this post

    Any Ideas please?
  3. Kalina
    Admin
    Kalina avatar
    918 posts

    Posted 15 Mar 2011 Link to this post

    Hello Mammu,

    Please excuse us for the delay.
    I tried to make a sample and reproduce the issue locally but without success.
    Could you please send us a simplified working page that illustrates your implementation where we will be able to observe the issue?

    Thank you in advance.

    Kind regards,
    Kalina
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
  4. Mammu
    Mammu avatar
    9 posts
    Member since:
    Jan 2010

    Posted 15 Mar 2011 Link to this post

    Hi Kalina,

    Please find the sample page below:

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="MultiSelectComboBox.aspx.cs" Inherits="Prototype.Test" %>
     
    <%@ Register Assembly="Telerik.Web.UI" Namespace="Telerik.Web.UI" TagPrefix="telerik" %>
     
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
     
    <head runat="server">
        <title>Untitled Page</title>
        <telerik:RadScriptBlock ID="RadScriptBlock1" runat="server">  
            <script type="text/javascript">
                // Function that gets triggered when the checkbox for multi select RadCombo is clicked
                function MultiSelectCheckboxOnClick(checkBox, clientID) {
                    var combo = $find(clientID);
                    //holds the text of all checked items
                    var text = "";
                    //holds the values of all checked items
                    var values = "";
                    //get the collection of all items
                    var items = combo.get_items();
                    //enumerate all items
                    for (var i = 0; i < items.get_count(); i++) {
                        var item = items.getItem(i);
                        //get the checkbox element of the current item
                        var checkBox = item.get_element().getElementsByTagName("input")[0];
                        if (checkBox.checked) {
                            text += item.get_text() + ",";
                            values += item.get_value() + ",";
                        }
                    }
                    text = removeLastComma(text);
                    values = removeLastComma(values);
     
                    if (text.length > 0) {
                        combo.set_text(text);
                        combo.set_value(values);
                    }
                    else {
                        combo.set_text("");
                        combo.set_value("");
                    }
                }
     
                // Function to remove the last comma from the given string
                function removeLastComma(str) {
                    return str.replace(/,$/, "");
                }
                 
                // Function to stop the propogation of selecting the item of the combobox
                function StopPropagation(e) {
                    //cancel bubbling
                    e.cancelBubble = true;
                    if (e.stopPropagation) {
                        e.stopPropagation();
                    }
                }
            </script
        </telerik:RadScriptBlock>
    </head>
    <body>
        <form id="form1" runat="server">
        <div>
            <telerik:RadScriptManager ID="RadScriptManager1" runat="server"></telerik:RadScriptManager>
            <telerik:RadComboBox ID="MultiSelectComboBox"
                                 AllowCustomText="true"
                                 EmptyMessage="Select Item"
                                 ItemsPerRequest="10"
                                 ShowMoreResultsBox="true"
                                 EnableVirtualScrolling="true"
                                 EnableAutomaticLoadOnDemand="true"
                                 OnDataBound="OnRadComboItemsDataBound"
                                 Width="200px"
                                 Height="200px"
                                 runat="server">
            </telerik:RadComboBox>
            <br />
            <telerik:RadAjaxPanel ID="RadAjaxPanel1" runat="server">
                <asp:Button runat="server" Text="Select" ID="Button1" OnClick="Button1_OnClick" />
                <br />
                <asp:Label ID="Result" runat="server"></asp:Label>
            </telerik:RadAjaxPanel>
            <br />
        </div>
        </form>
    </body>
    </html>
    using System;
    using System.Collections;
    using System.Collections.Generic;
    using System.Linq;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using CustomTemplates;
    using Telerik.Web.UI;
     
    namespace Prototype
    {
        /// <summary>
        /// Demo class
        /// </summary>
        public partial class Test : Page
        {
            /// <summary>
            /// Gets the combo box selected values as list.
            /// </summary>
            /// <param name="radComboBox">The RAD combo box.</param>
            /// <returns></returns>
            public string[] GetComboBoxSelectedValuesAsList(RadComboBox radComboBox)
            {
                string[] selectedValueArray = radComboBox.SelectedValue.Split(',');
                var returnValueArray = new string[selectedValueArray.Length];
     
                for (int i = 0; i < selectedValueArray.Length; i++)
                {
                    // Cannot use FindItemByValue or other Finds when LoadOnDemand is enabled
                    returnValueArray[i] = radComboBox.FindItemByValue(selectedValueArray[i]).Value;
                }
     
                return returnValueArray;
            }
     
            /// <summary>
            /// Gets the drop down data.
            /// </summary>
            /// <returns></returns>
            public IEnumerable GetDropDownData()
            {
                var returnData = new List<DummyObject>();
     
                for (int i = 0; i < 1000; i++)
                {
                    returnData.Add(new DummyObject {Value = i, Text = "Item " + i});
                }
     
                return returnData;
            }
     
            /// <summary>
            /// Raises the <see cref="E:System.Web.UI.Control.Init"/> event to initialize the page.
            /// </summary>
            /// <param name="e">An <see cref="T:System.EventArgs"/> that contains the event data.</param>
            protected override void OnInit(EventArgs e)
            {
                MultiSelectComboBox.ItemTemplate = new MultiSelectTemplate();
                MultiSelectComboBox.DataSource = GetDropDownData();
                base.OnInit(e);
            }
     
            /// <summary>
            /// Handles the Load event of the Page control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
            protected void Page_Load(object sender, EventArgs e)
            {
                if (!IsPostBack)
                {
                    MultiSelectComboBox.DataTextField = "Text";
                    MultiSelectComboBox.DataValueField = "Value";
                    MultiSelectComboBox.Text = "Item 0,Item 1,Item 15";
                }
            }
     
     
            /// <summary>
            /// Called when [RAD combo items data bound].
            /// </summary>
            /// <param name="sender">The sender.</param>
            /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
            protected void OnRadComboItemsDataBound(object sender, EventArgs e)
            {
                var comboBox = sender as RadComboBox;
     
                if (comboBox != null)
                {
                    var comboBoxSelectedItems =
                        comboBox.Items.Where(item => item.Value == "0" || item.Value.Equals("1") || item.Value.Equals("15"));
     
                    if (comboBoxSelectedItems.Count() > 0)
                    {
                        foreach (var comboBoxSelectedItem in comboBoxSelectedItems.Where(comboBoxSelectedItem => comboBoxSelectedItem != null))
                        {
                            ((CheckBox) comboBoxSelectedItem.FindControl("MultiSelectCheckBox")).Checked = true;
                        }
                    }
                }
            }
     
            /// <summary>
            /// Handles the Click event of the RadButton1 control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
            protected void Button1_OnClick(object sender, EventArgs e)
            {
                Result.Text = "The selected items are " + MultiSelectComboBox.Text + ". The selected Values are : " +
                              MultiSelectComboBox.SelectedValue;
            }
     
            /// <summary>
            /// Dummay Object class used to provide the text and value for RadComboBox
            /// </summary>
            public class DummyObject
            {
                /// <summary>
                /// Gets or sets the text.
                /// </summary>
                /// <value>
                /// The text.
                /// </value>
                public string Text { get; set; }
     
                /// <summary>
                /// Gets or sets the value.
                /// </summary>
                /// <value>
                /// The value.
                /// </value>
                public int Value { get; set; }
            }
        }
    }

    namespace CustomTemplates
    {
        using System;
        using System.Web.UI;
        using System.Web.UI.WebControls;
        using Telerik.Web.UI;
     
        /// <summary>
        /// Multi Select Template
        /// </summary>
        public class MultiSelectTemplate : ITemplate
        {
            /// <summary>
            /// When implemented by a class, defines the <see cref="T:System.Web.UI.Control"/> object that child controls and templates belong to. These child controls are in turn defined within an inline template.
            /// </summary>
            /// <param name="container">The <see cref="T:System.Web.UI.Control"/> object to contain the instances of controls from the inline template.</param>
            public void InstantiateIn(Control container)
            {
                var checkBox = new CheckBox { ID = "MultiSelectCheckBox", CssClass = "multiSelectCheckBox" };
                checkBox.Init += MultiSelectCheckBoxInit;
                container.Controls.Add(checkBox);
     
                var text = new Label { ID = "ItemLabel", AssociatedControlID = "MultiSelectCheckBox", Text = "Text" };
                text.DataBinding += MultiSelectTextDataBinding;
                container.Controls.Add(text);
            }
     
            /// <summary>
            /// Handles the DataBinding event of the text control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
            protected void MultiSelectTextDataBinding(object sender, EventArgs e)
            {
                var target = sender as Label;
                WebControl container;
                ControlItemContainer itemContainer;
     
                try
                {
                    if (target != null)
                    {
                        container = target.BindingContainer as WebControl;
                        if (container != null)
                        {
                            container.Attributes.Add("onclick", "StopPropagation(event)");
                            itemContainer = container.Parent as ControlItemContainer;
                            if (itemContainer != null)
                            {
                                var itemText = DataBinder.Eval(container, itemContainer.DataTextField) as string;
                                target.Text = itemText;
                            }
                        }
                    }
                }
                catch (InvalidCastException)
                {
                    throw new InvalidCastException("The Binding Container for this Control should inherit from WebControl");
                }
            }
     
            /// <summary>
            /// Handles the Init event of the checkBox control.
            /// </summary>
            /// <param name="sender">The source of the event.</param>
            /// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
            protected void MultiSelectCheckBoxInit(object sender, EventArgs e)
            {
                var checkBox = sender as CheckBox;
                if (checkBox != null)
                {
                    checkBox.Attributes.Add(
                                            "onclick",
                                            "MultiSelectCheckboxOnClick(this, '" + checkBox.BindingContainer.Parent.ClientID +
                                            "')");
                }
            }
        }
    }


    Thanks in advance!!!
  5. Answer
    Kalina
    Admin
    Kalina avatar
    918 posts

    Posted 18 Mar 2011 Link to this post

    Hi Mammu,

    Thank you for the runnable code provided.
    Let me suggest you assign unique IDs at checkbox controls by handling the OnClientItemsRequested event in this way:
    <telerik:RadComboBox ID="MultiSelectComboBox"
                        OnClientItemsRequested="OnClientItemsRequested"
                         AllowCustomText="true"
                         EmptyMessage="Select Item"
                         ItemsPerRequest="10"
                         ShowMoreResultsBox="true"
                         EnableVirtualScrolling="true"
                         EnableAutomaticLoadOnDemand="true"
                         OnDataBound="OnRadComboItemsDataBound"
                         Width="200px"
                         Height="200px"
                         runat="server">
    </telerik:RadComboBox>

    function OnClientItemsRequested(sender, eventArgs)
    {
     
        var items = sender.get_items();
         
        for (var i = 0; i < items.get_count(); i++) {
         
            var item = items.getItem(i);
            var checkBox = item.get_element().getElementsByTagName("input")[0];
            checkBox.id = "MultiSelectCheckBox_ForItem_" + item.get_value();
             
        }
    }

    I hope this helps.

    Kind regards,
    Kalina
    the Telerik team
  6. Mammu
    Mammu avatar
    9 posts
    Member since:
    Jan 2010

    Posted 18 Mar 2011 Link to this post

    Hi Kalina,

    Thank you for your response. I think I got this working. I appreciate your help.

    Thank You
Back to Top