AjaxDataControls within user controls, multiple instances on one page

Last post 10-06-2009 8:47 AM by dmohana. 15 replies.
Page 1 of 2 (16 items) 1 2 Next >
Sort Posts: Previous Next
  • 04-19-2009 4:30 PM

    AjaxDataControls within user controls, multiple instances on one page

    I have a question regarding AjaxDataControls and their use within user controls.

    Inside a user control I have a GridView, something like this:

    function pageLoad(sender, e) {
    Cuyahoga.Modules.CatMod.Web.MyWebService.Test_Method(onLoadSuccess);
    alert('pageLoad fired.');
    }

    function onLoadSuccess(result) {
    GridView2.set_dataSource(result);
    GridView2.dataBind();
    alert('onLoadSuccess fired.');
    }

    The user control populates when there is only one instance added to the page. It does not when there are multiple instances.

    In the function onLoadSuccess, when setting the datasource and databinding, the name 'Gridview2' is explicit and therefore the same in all instances rendered to HTML. The last instance of the 'Gridview2' only is populated.

    I thought that maybe something like this:

    var gridView = $('<%= GridView2.ClientID %>');
    gridView.set_dataSource(result);
    gridView.dataBind();

     

    Obviously this does not work, but it was my first thought (JQuery). Is there a way to do this?

    I can register code to the page from the control but how do I databind the relevant instance of the GridView control? (or any other control for that matter :) )
  •  Advertisement

    Featured Advertisement

     
  • 04-20-2009 2:59 PM In reply to

    • Sonu
    • Top 10 Contributor
    • Joined on 05-22-2006
    • Montreal / Canada
    • Slacker
    • Points 12,183
    • MVP

    Re: AjaxDataControls within user controls, multiple instances on one page

    I have used multiple instances of the ADC controls on the same page without any problems. You are using the same variable name for all controls? I am not quite sure if I understand. Can you please elaborate?

    [MVP since 2005] [MCAD]
    Webmaster of DotNetSlackers
    Question or Suggestion?
    Feel free to ask my any .NET question
    Our Posting FAQ
  • 04-20-2009 3:29 PM In reply to

    Re: AjaxDataControls within user controls, multiple instances on one page

    I will try to explain more clearly.

    I have one page and one user control.

    The user control contains one Ajax Data Controls GridView and some code to populate it like this:

    function pageLoad(sender, e) {
    Cuyahoga.Modules.CatMod.Web.MyWebService.Test_Method(onLoadSuccess);
    alert('pageLoad fired.');
    }

    function onLoadSuccess(result) {
    GridView1.set_dataSource(result);
    GridView1.dataBind();
    alert('onLoadSuccess fired.');
    }

    When one instance of the user control is added to the page it populates.

    When more than one is added to the page only the last instance populates.

    How can a GridView or any other Ajax Data Control be INSIDE a user control and used multiple times on the same page?

    When a standard GridView is added to a page and populated it works fine. Since 'GridView1' is referenced explicitly when multiple instances are added to a single page then this does not work. This is the problem.

    You ask above: You are using the same variable name for all controls?

    Since they are inside the user control and used many times then yes. Is there another way to reference the controls for databinding?

     

     

  • 04-20-2009 3:38 PM In reply to

    • Sonu
    • Top 10 Contributor
    • Joined on 05-22-2006
    • Montreal / Canada
    • Slacker
    • Points 12,183
    • MVP

    Re: AjaxDataControls within user controls, multiple instances on one page

    Ah... Since both use the same name, you will see problems. You can try to rename the control via js, not sure if this will work though. Or you could create a new property inside your usercontrol called "ADCId" and set that declarative. You would then use that property to set the name of your ADC controls from the codebehind of your usercontrol.

    <uc1:ADC ADCId="gw1" runat="server" />
    <uc1:ADC ADCId="gw2" runat="server" /> 

    etc..

    [MVP since 2005] [MCAD]
    Webmaster of DotNetSlackers
    Question or Suggestion?
    Feel free to ask my any .NET question
    Our Posting FAQ
  • 04-20-2009 4:01 PM In reply to

    Re: AjaxDataControls within user controls, multiple instances on one page

     Hmmm... Ok, I will look at that. Thanks. :)

  • 04-22-2009 2:39 PM In reply to

    Re: AjaxDataControls within user controls, multiple instances on one page

     OK, I have found a solution to this. I will try to explain clearly.

    The problem was that databinding the Ajax Data Control GridView is done like this:


     <script type="text/javascript">
        function pageLoad(sender, e) {
            Cuyahoga.Modules.CatMod.Web.MyWebService.Test_Method(onLoadSuccess);
            //alert('pageLoad fired.');
        }

        function PopulateADCGridView1(result) {
            ADCGridView1.set_dataSource(result);
            ADCGridView1.dataBind();
            alert('onLoadSuccess PopulateADCGridView1 Static fired');
        }
    </script>

    The databinding is by reference to the 'ADCGridView1' explicitly. Therefore the controls are named identically when multiple instances of the control are used. Boom! Not work.

    So you have to dynamically create the control and add it to the update panel. You then use the controls ID and ClientID to generate the javascript to populate it via the web service of your choice.

    I generated the ID of the control by using a random string generator. This was just to make it easy. There will be a better way (like adding the property in the page parkup, but the CMS I use does not allow this) The code for this is here:


            private string RandomString(int size, bool lowerCase)
            {
                StringBuilder builder = new StringBuilder();
                Random random = new Random();
                char ch;
                for (int i = 0; i < size; i++)
                {
                    ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));
                    builder.Append(ch);
                }
                if (lowerCase)
                    return builder.ToString().ToLower();
                return builder.ToString();
            }

    Create a property for the Ajax Data Controls ID to be stored in. This will store the Ajax Data Controls GridView ID from the current user control instance.


            //GridView ID to be set for each instance
            private String _ADCGridViewID;
            public String ADCGridViewID {
                get{ return _ADCGridViewID; }
                set{_ADCGridViewID = value; }
            }

    Then inside the PageLoad of the control code create the control and add them to the Update Panel:


            protected void Page_Load(object sender, EventArgs e)
            {
                this.ADCGridViewID = "ADCGV_"+RandomString(8,true); //String variable

                AjaxDataControls.GridView dGV = new AjaxDataControls.GridView();
                dGV.ID = ADCGridViewID;
                dGV.EnableViewState = true;

                UpdatePanel uDP = this.FindControl("UpdatePanel1") as UpdatePanel;
                uDP.ContentTemplateContainer.Controls.Add(dGV);

    }

    Then also inside the PageLoad, create the ClientScriptManager to add the javascript required to populate your control and also register 'add_load' event scripts to make them work on load (this was the tricky part).


    //Register JavaScript via RegisterStartupScript
                ClientScriptManager csm = Page.ClientScript;

                csm.RegisterStartupScript(this.GetType(), "pageLoad"+ ADCGridViewID,
                @"<script type='text/javascript'>" + System.Environment.NewLine +
                @"function onLoad"+ADCGridViewID+"(result) {" + System.Environment.NewLine +
                ADCGridViewID + @".set_dataSource(result);" + System.Environment.NewLine +
                ADCGridViewID + @".dataBind();" + System.Environment.NewLine +
                //@"alert('onLoad " + ADCGridViewID + " fired');" + System.Environment.NewLine +
                @"}" + System.Environment.NewLine +
                //
                @"function populate"+ADCGridViewID+"() {" + System.Environment.NewLine +
                @"  Cuyahoga.Modules.CatMod.Web.MyWebService.Test_Method(onLoad"+ADCGridViewID+");" + System.Environment.NewLine +
                //@"  alert('function populate" + ADCGridViewID + " fired.');" + System.Environment.NewLine +
                @"}" + System.Environment.NewLine +
                //
                @"function populate() {" + System.Environment.NewLine +
                @"  Cuyahoga.Modules.CatMod.Web.MyWebService.Test_Method(PopulateADCGridView1);" + System.Environment.NewLine +
                @"}" + System.Environment.NewLine +
                //
                @"Sys.Application.add_load(populate" + ADCGridViewID + ");" + System.Environment.NewLine +
                @"</script>" + System.Environment.NewLine + System.Environment.NewLine);

    This will generate the call to the web service and populate the control based upon the ID and ClientID of the dynamically created Ajax Data Control.

    I have added 5 instances of the control to a page and they all populate :)

  • 04-22-2009 2:47 PM In reply to

    • Sonu
    • Top 10 Contributor
    • Joined on 05-22-2006
    • Montreal / Canada
    • Slacker
    • Points 12,183
    • MVP

    Re: AjaxDataControls within user controls, multiple instances on one page

    Awesome. Great to see that you got it working. Thanks for posting your code. It will surely help others.

    [MVP since 2005] [MCAD]
    Webmaster of DotNetSlackers
    Question or Suggestion?
    Feel free to ask my any .NET question
    Our Posting FAQ
  • 04-23-2009 4:49 PM In reply to

    Re: AjaxDataControls within user controls, multiple instances on one page

    OK, this is the weirdest thing I have ever seen!

    When debugging, and when (and ONLY when) a breakpoint is added to the 'csm.RegisterStartupScript' line this is rendered to the page:

     <script type='text/javascript'>
    function onLoadADCGV_yfklzilr(result) { ADCGV_yfklzilr.set_dataSource(result);
    ADCGV_yfklzilr.dataBind(); } function populateADCGV_yfklzilr() { Cuyahoga.Modules.CatMod.Web.MyWebService.Test_Method(onLoadADCGV_yfklzilr); }
    Sys.Application.add_load(populateADCGV_yfklzilr);
    </script>

    <script type='text/javascript'>
    function onLoadADCGV_tltmkngk(result) { ADCGV_tltmkngk.set_dataSource(result);
    ADCGV_tltmkngk.dataBind(); }
    function populateADCGV_tltmkngk() { Cuyahoga.Modules.CatMod.Web.MyWebService.Test_Method(onLoadADCGV_tltmkngk); } Sys.Application.add_load(populateADCGV_tltmkngk);
    </script>

    <script type='text/javascript'>
    function onLoadADCGV_scnjgvoe(result) { ADCGV_scnjgvoe.set_dataSource(result);
    ADCGV_scnjgvoe.dataBind(); }
    function populateADCGV_scnjgvoe() { Cuyahoga.Modules.CatMod.Web.MyWebService.Test_Method(onLoadADCGV_scnjgvoe); } Sys.Application.add_load(populateADCGV_scnjgvoe);
    </script>

    So the 3 code blocks are rendered (there are 3 because there are 3 controls on the page, 1 each.)

    Now, I took something for granted. I assumed that code acts the same when in debug and when not. If I was to run the same page but this time NOT in debug, only the last block of javascript (for the last instance of the user control) is rendered and therefore populated.

    If that is not weird enough, if I remove the breakpoint from the 'csm.RegisterStartupScript' line of code and REMAIN in debug, then only the last block of code is rendered and therefore populated.

    So... I think I will just give up. Unless anyone can explain this?

  • 04-24-2009 7:41 AM In reply to

    • Sonu
    • Top 10 Contributor
    • Joined on 05-22-2006
    • Montreal / Canada
    • Slacker
    • Points 12,183
    • MVP

    Re: AjaxDataControls within user controls, multiple instances on one page

    I have never seen this. Can you post your code that you use to register the script?

    [MVP since 2005] [MCAD]
    Webmaster of DotNetSlackers
    Question or Suggestion?
    Feel free to ask my any .NET question
    Our Posting FAQ
  • 04-24-2009 8:27 AM In reply to

    Re: AjaxDataControls within user controls, multiple instances on one page

    It was the code above that was acting strange.

    That was one of the most bizarre things I have ever seen. I have changed the code to (below). It now works. It does exactly the same thing, just that this time it works both in debug and live. I have never seen the same code behave differently in debug to live before. That was frustrating.

    The code below works.

    =====================================

    //GridView ID to be set for each instance
    private String _ADCGridViewID;

    public String ADCGridViewID {
                get{ return _ADCGridViewID; }
                set{_ADCGridViewID = value; }
            } 

    private string RandomName(int size)
            {
                return System.Guid.NewGuid().ToString().Replace("-", "").Substring(0, size);
            }

    protected void Page_Load(object sender, EventArgs e)        {   

    //Set generated control ID in this User Controls Param
                this.ADCGridViewID = "adc_gv_" + RandomName(8);

    AjaxDataControls.GridView dGV = new AjaxDataControls.GridView();
                dGV.ID = ADCGridViewID;
                PlaceHolder uPL = this.FindControl("PlaceHolder1") as PlaceHolder; //Place the created control where you want it.
                uPL.Controls.Add(dGV);

    ClientScriptManager csm = Page.ClientScript;
                csm.RegisterStartupScript(this.GetType(), System.Guid.NewGuid().ToString(),
                @"<script type='text/javascript'>//<![CDATA[" + System.Environment.NewLine +
                    @"function onLoad" + ADCGridViewID + "(result) {" +
                    @"var " + ADCGridViewID + @" = $find('" + dGV.ClientID + "');" +
                        ADCGridViewID + @".set_dataSource(result);" +
                        ADCGridViewID + @".dataBind();" +
                    @"}" +
                    //
                    @"function populate" + ADCGridViewID + "() {" +
                        @"  Cuyahoga.Modules.CatMod.Web.MyWebService.Test_Method(onLoad" + ADCGridViewID + ");" +
                    @"}" + System.Environment.NewLine +
                    @"Sys.Application.add_load(populate" + ADCGridViewID + ");" + System.Environment.NewLine +
                @"//]]></script>");

    }

  • 04-24-2009 8:46 AM In reply to

    • Sonu
    • Top 10 Contributor
    • Joined on 05-22-2006
    • Montreal / Canada
    • Slacker
    • Points 12,183
    • MVP

    Re: AjaxDataControls within user controls, multiple instances on one page

    Bizarre. I am happy that you got it working at the end though.

    I would have probably used this method to implement dynamic controls:

    <AjaxData:GridView runat="server" id="<% =ADCId %>"></AjaxData:GridView>

    In the codebedind:

    Private _adcId As String

    Public Property ADCId() As String
      Get
        Return _adcId
      End Get
      Set(ByVal value As String)
        _adcId = value
      End Set
    End Property

    Usage in the aspx page:

    <%@ Register src="ADC.ascx" tagname="ADC" tagprefix="uc1" %>


    <uc1:ADC ID="ADC1" runat="server" ADCId="gridView1" />
    <uc1:ADC ID="ADC1" runat="server" ADCId="gridView2" />
    <uc1:ADC ID="ADC1" runat="server" ADCId="gridView3" />

     

    [MVP since 2005] [MCAD]
    Webmaster of DotNetSlackers
    Question or Suggestion?
    Feel free to ask my any .NET question
    Our Posting FAQ
  • 04-24-2009 9:33 AM In reply to

    Re: AjaxDataControls within user controls, multiple instances on one page

     Unfortunately that was not an option as the user controls are themselves added to the page dynamically as part of a wider CMS (unless I misunderstand). Anyway, it works!

    Thanks for your help :)

     

  • 04-24-2009 9:42 AM In reply to

    • Sonu
    • Top 10 Contributor
    • Joined on 05-22-2006
    • Montreal / Canada
    • Slacker
    • Points 12,183
    • MVP

    Re: AjaxDataControls within user controls, multiple instances on one page

    Ah. Well at last everything worked out for you.

    [MVP since 2005] [MCAD]
    Webmaster of DotNetSlackers
    Question or Suggestion?
    Feel free to ask my any .NET question
    Our Posting FAQ
  • 05-04-2009 4:42 AM In reply to

    • huanhvhd
    • Top 150 Contributor
    • Joined on 04-14-2009
    • Wannabe Slacker
    • Points 50

    Re: AjaxDataControls within user controls, multiple instances on one page

    Hi Sonu and Constructor,

    Do you have any document or example that create Pager from C# code?

    I was success with Constructor's sample, but can not add Pager into control. I was create new Pager object like:

                    AjaxDataControls.Pager pager = new AjaxDataControls.Pager();
                    pager.ID = this.ADCPagerID;
                    pager.PageSize = PageSize;
                    pager.PageChangedEvent = "pageChanged" + ADCPagerID;
                    pager.CssClass = "PagerRowStyle";
                    pager.SliderSize = 5;
                    pager.UseSlider = true;
                    pager.ShowFirstAndLast = true;
                    pager.ShowPreviousAndNext = true;

    then Add pager into Place Holder:

                    PlaceHolder plcRepeater = this.FindControl("plcRepeater") as PlaceHolder;
                    plcRepeater.Controls.Add(rpt);
                    plcRepeater.Controls.Add(pager);

    I also add a function into JavaScript code like:

                        // pageChanged
                        @"function pageChanged" + ADCPagerID + "(sender, e) {" +
                            @"var " + ADCRepeaterID + @" = $find('" + rpt.ClientID + "');" +
                            @"" + ADCRepeaterID + ".set_pageIndex(e.get_newPageIndex());" +
                            @"populate" + ADCRepeaterID + "();" +
                        @"}" + System.Environment.NewLine +

    But if runing, I only see the Repeater data, Pager data is not display, althought I see a div element that contain ID of Pager.

    Do you have any suggest?

    Thanks

  • 05-04-2009 5:13 AM In reply to

    Re: AjaxDataControls within user controls, multiple instances on one page

    I have downloaded the src from the svn repository and there are samples in the 'Sample\Repeater' folder.

    It should be simple to translate this code using the same methods as before. I will take a look later when I have finished my work and try to post a solution, or add a repeater to the test project on Cuyahoga forum. I may do examples for all Ajax Data Controls in that test project.

Page 1 of 2 (16 items) 1 2 Next >