Wednesday, March 21, 2012

Partial Postbacks and JScript Changes Previously Made on the Client Side

Hello, thank you in advance for taking the time to read this.

I have a Gridview on which I use client-side JScript to add an empty row (hidden) after binding. I place several hidden DIVS in my Gridview template, and then when a user clicks on one of several "expand" buttons in the Gridview, the empty row is made visible and the innerHTML is swapped from the appropriate hidden DIV. This makes the empty row sort of a "Jack of all trades" in that it can display numerous different things as needed by the user.

I am attaching the JScript function below for reference. The empty DIVS are inserted into the client page in the Codebehind using the Gridview's OnRowDataBound handler, but I have no clue how to add a row dynamically server-side, so I went with the client-side script to get the container row done.

Everything works great until you do a sort. The control is AJAX-enabled, so refreshes through a partial postback. Trouble is that the client-side code that adds all the rows does not fire when the grid is refreshed, so none of the "Expand" icons work after the Gridview has been refreshed, because there is no hidden row to make visible and swap content with.

After all this, my question is: How might I:

A) insert an empty row programatically server-side, or

B) fire a client-side script at databinding on a partial postback.

Oh, and I am a pure short-busser when it comes to .NET -- love it but am just now moving up from legacy and feel like a complete idiot. Please speak slowly if you care to answer, and forgive my ignorance.

Javascript adding the rows follows -- I am assigning an ID reference to each row using the "Tracking" field - a unique DB column.

Thanks again for reading, and for any information or hlp you can provide.

Shannon

function fixGrid(idGrid){

var al ="";

var rowcount = 0;for (var t=0;t<idGrid.childNodes[0].childNodes.length-1;t++){

thisName = idGrid.childNodes[0].childNodes[t].nodeName;

if(thisName=="TR"){

rowcount ++;

if(rowcount > 1){

lastCell = idGrid.childNodes[0].childNodes[t].childNodes.length;

thisCell = idGrid.childNodes[0].childNodes[t].childNodes[lastCell-1];

thisTrack = idGrid.childNodes[0].childNodes[t].childNodes[lastCell-2].innerText;

newTR = document.createElement('tr');

newRow1 = newTR.cloneNode(true);

newTD = document.createElement('td');newCol1 = newTD.cloneNode(true);

newCol1.colSpan=9;

newCol1.style.visibility='hidden';

newCol1.style.display='none';

newCol1.id ="td-"+thisTrack;

newCol1.innerHTML="Nothing";

newTR.appendChild(newCol1);

nextRow = idGrid.childNodes[0].childNodes[t].nextSibling;

tableTop = idGrid.childNodes[0].childNodes[t].parentNode;

tableTop.insertBefore(newTR,nextRow);

t++;

}

}else{

alert(thisName);

}

}

returnfalse;

}

Problem solved! I figured I would answer myself for the benefit of future readers.

The call to the client side code in my original post is made fromfixGrid(document.all.gridedit)when the page originally loads.

Obviously, I only want to add the empty container rows once, so I only want this script to be called once each time UpdatePanel1 refreshes, and not if any other panel does. Got it to work that way usingRegisterClientScriptBlock with the update panel ID:

protectedvoid Page_PreRender(object sender,EventArgs e)

{

string script =@."fixGrid(document.all.gridedit);";ScriptManager.RegisterClientScriptBlock(

UpdatePanel1,

typeof(Page),

"ToggleScript",

script,

true);

}

No comments:

Post a Comment