This case is going to sound complicated, but it's not that bad. The javascript at the end of this code seems to be sound.
EDIT: Here's the page running on a live server. The first example doesn't alternate between open and closed because I ripped out a lot of code in order to narrow the example down as much as I could.
http://69.64.80.239/tmp/borked2.aspx
There are two cases listed in the following client code. The first case posts back when an imagebutton is clicked, and adds a call to the large javascript function, using the clientid of the imagebutton as the argument.
The second case simply uses an onClientClick, and executes the javascript without a postback.
Both methods accomplish the display and hiding of the textbox that should appear. However, with the postback method, commas are inserted every time you go back and forth - first 1 then 3 then 7 then 15 then 31. This odd behaviour does not occur with case #2, which makes me believe that the javascript in this case is sound.
When the postback occurs, a 'value=","' attribute appears in my textbox that was not there before. the increasing numbers of commas fit into the newly added attribute.
This case is extremely stripped down so as to highlight the problem effectively. Ultimately this is causing a detailsview I am performing the same copy on to add a comma to the beginning of every form value that it submits.
I'm completely stumped, so I'm just going to post the code as well as I can! Any ideas would be appreciated!
<h5>CASE 1: Using Serverside postback to insert Javascript into a Literal</h5>
<table><tr><td>
<asp:ImageButton id="CollapseExpand" runat="server" ImageUrl="/images/plus.gif" src="/images/plus.gif"
AlternateText="Hide Tasks" Width="12" Height="12" onclick="CollapseExpand_Click"
/>
<div style="display:none">
<asp:TextBox runat="server" ID="Textbox1"></asp:TextBox>
<asp:Button runat="server" ID="btnSubmit1" Text="Submit 1" />
</div>
<asp:Literal runat="server" ID="ScriptAnchorTest"></asp:Literal>
</td></tr></table>
CASE 1 Codebehind
protected void CollapseExpand_Click(object sender, ImageClickEventArgs e)
{
Literal l = (Literal)this.ScriptAnchorTest;
l.Text = "<script type=\"text/javascript\">Expand(document.getElementById('" + this.CollapseExpand.ClientID + "'));</script>";
}
CASE 2: Executing Javascript Clientside directly
<asp:ImageButton id="CollapseExpand2" runat="server" src="/images/plus.gif"
AlternateText="Hide Tasks" Width="12" Height="12" onClientClick="Expand(this); return false;"
/>
<div style="display:none">
<asp:TextBox runat="server" ID="TextBox2"></asp:TextBox>
<asp:Button runat="server" ID="btnSubmit2" Text="Submit 2" />
</div>
</td></tr></table>
// The Javascript Function function Expand(image, index) { // get the source of the image var src = image.getAttribute("src");
// if src is currently "plus.", then toggle it to "minus.png"
if (src.indexOf("plus") > 0) {
// toggle the image
image.src = image.src.replace("plus", "minus");
var tr = image.parentNode.parentNode;
// Get a reference to the next row from where the image is
var next_tr = tr.nextSibling;
// Get a refernece to the <tbody> tag of the grid
var tbody = tr.parentNode;
// Get a reference to the image's column
var td = image.parentNode;
var detailnode
//loop through the content of the image's column. if hidden div is found, get a reference
for (var j = 0; j < td.childNodes.length; j++) {
if (td.childNodes[j].nodeType == 1) {
if (td.childNodes[j].nodeName.toLowerCase() == 'div') {
detailnode = td.childNodes[j].cloneNode(true);
}
}
}
// Create a new table row for "Expand"
var newtr = document.createElement('tr');
var newtd = document.createElement('td');
var newfirsttd = newtd.cloneNode(true);
/* insert an empty cell first */
newtr.appendChild(newfirsttd);
newtd.colSpan = 8;
// insert the hidden div's content into the new row
newtd.innerHTML = detailnode.innerHTML;
newtr.appendChild(newtd);
tbody.insertBefore(newtr, next_tr);
tr.className = "selected";
}
else {
image.src = src.replace("minus", "plus");
var row = image.parentNode.parentNode;
var rowsibling = row.nextSibling;
var rowparent = row.parentNode;
rowparent.removeChild(rowsibling);
}
I don't have time to read your entire code, but please pay attention to the following: you may be copying a HTML chunk and creating a clone of it in your code. This way, you actually get two textboxes with the same Id, although you see only one of them. At postback, the browser concatenates the values as a comma-separated list. For example, if you enter "Test1" and "Test2" in the textboxes, respectively, and then submit, both textboxes get the value doubled. Now, if you only expand one of them (the first, let's say), and submit, only the expanded one gets doubled again, while the one not expanded stays the same over postbacks.
For a solution, if you only need to show or hide a div, the best way is to do it from javascript, client side, by changing the style (visibility) of that div, and not by cloning it. This way, your function could be reduced to one line of code.
Sergiu is right, you are creating two html input with the same ID "Textbox1" as you can see in the screenshot captured using Firebug
This ends up concatenating the two values separated by a comma.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With