0

I have done a bit of searching, and tried several solutions from different posts, but can't seem to get them to work. The basic idea is this... I am customizing an existing usercontrol that lays dynamically generated data out into a single column table of rows. It then has an "edit" link button that does a postback and rebuilds the table with editable fields. I found some jQuery I am using to convert the table into a 2 row table, broken into multiple columns (much easier then trying to re-engineer the data creation/markup within the c#). When the page loads the first time, it works perfectly. However, when I click the "edit" linkbutton, it properly does the postback, but the jQuery doesn't fire. I have tried several configurations to no avail. Here is the jQuery:

private void RegisterScripts()
{
    StringBuilder sbScript = new StringBuilder();
    sbScript.Append("\tvar tables = $('table[id*=\"tblAttribute\"]');\n");
    sbScript.Append("\tfor (var i = 0; i < tables.length; i++) {\n");
    sbScript.Append("\t\tvar newTable = document.createElement('table');\n");
    sbScript.Append("\t\tvar columns = 2;\n");
    sbScript.Append("\t\tfor(var c = 0; c < columns; c++) {\n");
    sbScript.Append("\t\t\tnewTable.insertRow(c);\n");
    sbScript.Append("\t\t\tfor(var r = 1; r < tables[i].rows.length ; r++) {\n");
    sbScript.Append("\t\t\t\tnewTable.rows[c].insertCell(r-1);\n");
    sbScript.Append("\t\t\t\tnewTable.rows[c].cells[r-1].innerHTML = tables[i].rows[r].cells[c].innerHTML;\n");
    sbScript.Append("\t\t\t\tnewTable.rows[c].cells[r-1].className = tables[i].rows[r].cells[c].className;\n");
    sbScript.Append("\t\t\t\ttables[i].rows[r].style.display = 'none';\n");
    sbScript.Append("\t\t\t}\n");
    sbScript.Append("\t\t}\n");
    sbScript.Append("\t\tnewTable.className = tables[i].className;\n");
    sbScript.Append("\t\ttables[i].parentNode.appendChild(newTable);\n");
    sbScript.Append("\t}\n");

    Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "RowsToColumnsScript", sbScript.ToString(), true);

}

Here is the call within the Page_Load cycle:

protected void Page_Load(object sender, EventArgs e)
{
    RegisterScripts();
    // Other Stuff //
}

I have also tried replacing the RegisterClientScriptBlock() with a RegisterStartupScript() and got the same results. What am I missing?

EDIT 2: Here is the script as it is being added to the client page. I copied right out of the page source (minus my abbreviation):

<script type="text/javascript">
//<![CDATA[
var tables = $('table[id*="tblAttribute"]');
for (var i = 0; i < tables.length; i++) {
    var newTable = document.createElement('table');
    var columns = 2;
    for(var c = 0; c < columns; c++) {
        newTable.insertRow(c);
        for(var r = 1; r < tables[i].rows.length ; r++) {
            newTable.rows[c].insertCell(r-1);
            newTable.rows[c].cells[r-1].innerHTML = tables[i].rows[r].cells[c].innerHTML;
            newTable.rows[c].cells[r-1].className = tables[i].rows[r].cells[c].className;
            tables[i].rows[r].style.display = 'none';
        }
    }
    newTable.className = tables[i].className;
    tables[i].parentNode.appendChild(newTable);
}
// Other js registered from other usercontrols
</script>
gmaness
  • 154
  • 1
  • 12
  • 1
    Are you using an `UpdatePanel` or no? – Karl Anderson Dec 17 '13 at 20:29
  • 1
    You could place an alert or debugger instruction to see if the code is executed or not. – Claudio Redi Dec 17 '13 at 20:30
  • @KarlAnderson - No, I am not currently using an update panel. – gmaness Dec 17 '13 at 20:44
  • @ClaudioRedi - I have done that as well. This is how I have discovered that the code executes on initial page load, but not on postback. – gmaness Dec 17 '13 at 20:45
  • So the issue, despite the question title, is not firing jquery on postback...the problem is that `RegisterScripts` does not fire on postback? – ethorn10 Dec 17 '13 at 21:03
  • @ethorn10 - I'm not sure where you are drawing the distinction. My basic issue is that I need to run a chunk of jQuery every time the page loads, and/or does a PostBack. RegisterScripts() is just a method I created to encapsulate the script I want to run. I am open to any modifications of any of the code to accomplish that end goal. – gmaness Dec 17 '13 at 21:08
  • Can you show what the script looks like on the client end, instead of the stringbuilder append \n \t? I suspect that there is more to this... – ethorn10 Dec 17 '13 at 21:17
  • @ethorn10 - Okay, I added the client side script in the original post, though I don't know why it matters. The js works fine. – gmaness Dec 17 '13 at 21:30
  • @KarlAnderson I must stand corrected. It appears that there are update panels being created around each table as they are built. – gmaness Dec 18 '13 at 15:39

3 Answers3

1

try wrapping your jquery codes inside the ready function

$(function(){
    // place your code here
});

.

<script type="text/javascript">
$(function(){
    //<![CDATA[
    var tables = $('table[id*="tblAttribute"]');
  for (var i = 0; i < tables.length; i++) {
    var newTable = document.createElement('table');
    var columns = 2;
    for(var c = 0; c < columns; c++) {
        newTable.insertRow(c);
        for(var r = 1; r < tables[i].rows.length ; r++) {
            newTable.rows[c].insertCell(r-1);
            newTable.rows[c].cells[r-1].innerHTML = tables[i].rows[r].cells[c].innerHTML;
            newTable.rows[c].cells[r-1].className = tables[i].rows[r].cells[c].className;
            tables[i].rows[r].style.display = 'none';
        }
    }
    newTable.className = tables[i].className;
    tables[i].parentNode.appendChild(newTable);
  }
   // Other js registered from other usercontrols
});
</script>
0

First off, why don't you do something this...

string script = @"var tables = $('table[id*=\'tblAttribute\']');
   for (var i = 0; i < tables.length; i++) {
   //rest of your script
";

This will make your script much easier to read and make changes to. White space will be respected. So you don't need the \n and \t characters.

After that, view the resulting HTML in your browser and make sure it made it on there properly. Use your browser's debug tools to execute the script and see if any errors result.

Or just embed the script on the .aspx page instead of adding it from the Code Behind.

mason
  • 31,774
  • 10
  • 77
  • 121
  • The jQuery does work. It is not an issue of troubleshooting the jQuery, as it works properly on initial page load. It is an issue of trying to get it to execute again on a PostBack. – gmaness Dec 17 '13 at 20:47
0

Your javascript is expecting your tables to have an id that contains (*=) the string tblAttribute. It would appear that the javascript that creates the newly editable table does not add an id attribute to it. So, while your code-behind registers the script and it executes on each postback, you aren't seeing it because your newly editable table doesn't match the criteria $('table[id*="tblAttribute"]').

You will need to set up an id for the newly created table, but I can't guarantee that this methodology will work (depending on how your usercontrol builds up the various tables you may already have on the screen):

newTable.setAttribute("id", "tblAttribute" + i);

Obviously, id needs to be unique so simply adding your iterator to tblAttribute might create conflicts, but this should get you pointed in the right direction.

EDIT

Seeing your updated comment relating to the UpdatePanel, you might find this answer helpful: Registering scripts with an UpdatePanel

Community
  • 1
  • 1
ethorn10
  • 1,889
  • 1
  • 18
  • 29
  • great thought, however in this particular case, when the postback happens, a completely different table is rendered by the code behind that still meets the "tblAttribute" criteria. I have verified this with inspect element on the page after postback. It is actually why I use the "id*=" to make sure it picks both the pre-postback table, and the after-postback table. – gmaness Dec 18 '13 at 15:01