Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unsuccessful using .FindControl() on a div

Tags:

c#

asp.net

I have a html div element containing multiple divs with values that I want to put in an array server side!

my html divs look something like:

<div id="clientGrid" runat="server">
    <div id="cell_0_0" runat="server" class="box" onclick="clicked(this)">2</div>
    <div id="cell_0_1" runat="server" class="box" onclick="clicked(this)">1</div>
    <div id="cell_0_2" runat="server" class="box" onclick="clicked(this)">3</div>
    <div id="cell_0_3" runat="server" class="box" onclick="clicked(this)">4</div>

    <div id="cell_1_0" runat="server" class="box" onclick="clicked(this)">3</div>
    <div id="cell_1_1" runat="server" class="box" onclick="clicked(this)">2</div>
    <div id="cell_1_2" runat="server" class="box" onclick="clicked(this)">4</div>
    <div id="cell_1_3" runat="server" class="box" onclick="clicked(this)">1</div>

    <div id="cell_2_0" runat="server" class="box" onclick="clicked(this)">4</div>
    <div id="cell_2_1" runat="server" class="box" onclick="clicked(this)">3</div>
    <div id="cell_2_2" runat="server" class="box" onclick="clicked(this)">2</div>
    <div id="cell_2_3" runat="server" class="box" onclick="clicked(this)">1</div>
</div>

i want the values of these divs to go into an array server side. My current code looks like this:

for (int i = 0; i < _grid.getGridSize(); i++)
{
    for (int j = 0; j < _grid.getGridSize(); j++)
    {
        string divId = string.Format("cell_{0}_{1}", i.ToString(), j.ToString());
        Control div = clientGrid.findControl(divId);
        //more code underneath
    }
}

so the div id's are generated by the string format, no problem...

but the clientGrid.findControl always = null! even if i put the sting directly into the constructor like clientGrid.findControl("cell_0_0"); it still returns NULL! How is this possible?

It is my understanding the the findControl method finds server control elements with the string id?

I can't access the child divs directly like cell_0_0.clientID because the child divs are generated by the server at runtime.

on page load, this function is run...

    for (int i = 0; i < _grid.getGridSize(); i++)
    {
        for (int j = 0; j < _grid.getGridSize(); j++)
        {
            returnElement += " <div ";
            returnElement += "id=\"cell_" + i + "_" + j + "\" ";
            returnElement += "runat=\"server\" ";
            returnElement += "tabindex=\"-1\" ";
            returnElement += "class=\"box\" ";
            returnElement += "onclick=\"clicked(this);\" ";
            returnElement += "onkeypress=\"changeValue(event, this);\" ";
            returnElement += "style=\"top:" + top + "%; left:" + left + "%;\">";

            returnElement += test[i, j];

            returnElement += "</div>\n ";

            left = left + 20;
        }
        left = 0;
        top = top + 20;
    }
    return returnElement;

test[,] is a 2d array containing integer values. these divs are then put into clientGrid by clientGrid.innerHtml = allMyDivs

The users then edits the values of these divs to whatever they want, and then when the user clicks a button, the values of these divs need to somehow end up back in the serverside code so i can process them.

The clientGrid.control.count = 0 ... ??? so obviously... to the asp, these div elements do not exist... to asp.net... there is NOTHING inside the clientGrid div... but... the inspect element on my chrome browser says othervise! Whats Going On??

like image 922
AlexMorley-Finch Avatar asked May 23 '11 23:05

AlexMorley-Finch


2 Answers

Try using the asp:Panel control, which is an HTML div element, instead.

This would allow you to streamline your code:

Client Side:

<asp:Panel ID="clientGrid" runat="server" />

Server Side:

for each row
  for each col
    Panel p = new Panel();
    p.ID = "cell_" + row.tostring() + "_" col.tostring();
    p.Text = "&nbsp;";
    p.OnClientClick = "javascript:blah";
    clientGrid.Controls.Add(p);

You could even just use an asp:Placeholder and programmatically add all controls to that.

Then on postback you need to re-render the page in the init event. All controls that were dynamically created need to be re-created and re-added to the page on every single postback to restore the page state.

You can then do:

clientGrid.FindControl("Cell_0_0")

after you've re-rendered all of the controls.

There's a ton of posts about dynamically rendered asp.net controls all over the internet.

Another option is to the put a hidden control for each cell onto the form and, using javascript, place the value from each cell into the respective hidden control on submit and use Request.Form("Cell_0_0").

like image 135
AjAj Avatar answered Nov 18 '22 01:11

AjAj


Do you ever do _grid.AddControl(new cell) or clientGrid.AddControl(new cell)?

You are looping on _grid, but doing the search on clientGrid. Maybe it should be _grid.FindControl()?

Edit(1):

Then, you should do in your PreRender() foreach(Control c in clientGrid) Response.Write(c.ID + "<br />");

To get a list of all the ID's that clientGrid knows about. That should help you in your search for a solution.

Edit(2):

You could also try this ControlHelper method for getting a control, as the control could be burried deeper than you are expecting.

public static Control FindControlRecursive(this Control Root, string Id)
{
    if (Root.ID == Id)
        return Root;

    foreach (Control Ctl in Root.Controls)
    {
        Control FoundCtl = FindControlRecursive(Ctl, Id);
        if (FoundCtl != null)
            return FoundCtl;
    }

    return null;
}

Then use it in place of FindControl.

Edit(3):

I just pasted your markup into a form, added a blank box css class and a blank javascript clicked(object){;} handler, and then put this line in my Page_Load()

Control div = clientGrid.FindControl("cell_0_0");

It found it no problem. So you have something strange going on that isn't obvious from your code posting.

like image 2
Chuck Savage Avatar answered Nov 18 '22 02:11

Chuck Savage