Solved

ASP.NET Repeaters... Show / Hide buttons for product descriptions rendered in a repeater...

Posted on 2004-08-10
29
1,399 Views
Last Modified: 2008-03-10
Hi All,

I have a problem in something I want to do and would like some guidance or code to help me make this work.

I have thought of a simple example and created a template static webpage which should help get my idea across!!

Basically I have a repeater which repeats a tables with a header, product description and a footer for each product and the footer of each product has a show or hide description button in it.

If then the hide description button for that product is clicked I want the page to postback and hide the description for just that item, and then of course to swap the link in the footer for a show description link. Also I need show all descriptions, and hide all descriptions on the top of the page.

Here is the mock up example I have done to demonstrate what I mean:

http://www.createmail.co.uk/RepeaterProblemExample.htm

Any tips or help will be greatly appreciated!!

- Carl Southgate
0
Comment
Question by:createnetwork
  • 15
  • 14
29 Comments
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Hello Carl,

I am working on an example and this is the intermediate version:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
.style1 {
      color: #FFFFFF;
      font-weight: bold;
}
.style2 {color: #FFFFFF}
-->
</style>
<script>
function toggleTab(theLink){
  theTab = theLink.parentNode;
  while(theTab && theTab.nodeName!="TABLE"){
    theTab = theTab.parentNode;
  }
  if(theLink.innerHTML.indexOf("Show")>-1){
    if(theLink.innerHTML.indexOf("All")<0)
      theLink.innerHTML = theLink.innerHTML.replace("Show", "Hide");
    disp = "block";
  } else {
     if(theLink.innerHTML.indexOf("All")<0)
       theLink.innerHTML = theLink.innerHTML.replace("Hide", "Show");
    disp = "none";
  }
  allTabs = document.getElementsByTagName("TABLE");
  for(i=0;i<allTabs.length;i++){
    if(theTab==null && allTabs[i].className=="descTab"){
      allTabs[i].style.display = disp;
    } else {
    }
  }
  return false;
}
</script>
</head>

<body>
<div align="right"><a href="#" onClick="return toggleTab(this)">Show All Product Descriptions</a> / <a href="#" onClick="return

toggleTab(this)">Hide All Product Description</a> <br>
</div>
<hr>
<br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
  <tr>
    <td bgcolor="#999999"><span class="style1">Product Title One </span></td>
  </tr>
  <tr>
    <td><p>Product Description</p>
      <ul>
        <li>Line one</li>
        <li>Line two</li>
        <li>Line three    </li>
    </ul></td>
  </tr>
  <tr>
    <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="#" onClick="return toggleTab(this)">Hide Product

Description</a> </span></strong></div></td>
  </tr>
</table>
<br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
  <tr>
    <td bgcolor="#999999"><span class="style1">Product Title Two </span></td>
  </tr>
</table>
<br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
  <tr>
    <td><p>Product Description</p>
        <ul>
          <li>Line one</li>
          <li>Line two</li>
          <li>Line three </li>
      </ul></td>
  </tr>
</table>
<br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
  <tr>
    <td bgcolor="#999999"><span class="style1">Product Title Three </span></td>
  </tr>
  <tr>
    <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="#" onClick="return toggleTab(this)">Show Product

Description</a> </span></strong></div></td>
  </tr>
</table>
<br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
  <tr>
    <td bgcolor="#999999"><span class="style1">Product Title Four </span></td>
  </tr>
  <tr>
    <td><p>Product Description</p>
        <ul>
          <li>Line one</li>
          <li>Line two</li>
          <li>Line three </li>
      </ul></td>
  </tr>
</table>
</body>
</html>

Tell me wether this is the right direstion you want to go.

0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
How about this:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
.style1 {
      color: #FFFFFF;
      font-weight: bold;
}
.style2 {color: #FFFFFF}
-->
</style>
<script>
function toggleTab(theLink){
  theTab = theLink.parentNode;
  while(theTab && theTab.nodeName!="TABLE"){
    theTab = theTab.parentNode;
  }
  if(theLink.innerHTML.indexOf("Show")>-1){
    strFrom = "Show";
    strTo = "Hide";
    disp = "block";
  } else {
    strFrom = "Hide";
    strTo = "Show";
    disp = "none";
  }
  allTabs = document.getElementsByTagName("TABLE");
  for(i=0;i<allTabs.length;i++){
    if(theTab==null){
      if(allTabs[i].className=="prodTab"){
        tabLink = allTabs[i].rows[0].cells[1];
        tabLink.innerHTML = tabLink.innerHTML.replace(strFrom, strTo);
      }
      if(allTabs[i].className=="descTab"){
        allTabs[i].style.display = disp;
      }
    } else {
      if(allTabs[i]==theTab){
        theLink.innerHTML = theLink.innerHTML.replace(strFrom, strTo);
        allTabs[i+1].style.display = disp;
        break;
      }
    }
  }
  return false;
}
</script>
</head>

<body>
<div align="right"><a href="#" onClick="return toggleTab(this)">Show All Product Descriptions</a> / <a href="#" onClick="return

toggleTab(this)">Hide All Product Description</a> <br>
</div>
<hr>
<br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
  <tr>
    <td bgcolor="#999999"><span class="style1">Product Title One </span></td>
    <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="#" onClick="return toggleTab(this)">Hide Product

Description</a> </span></strong></div></td>
  </tr>
</table>
<br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
  <tr>
    <td><p>Product Description</p>
        <ul>
          <li>Line one</li>
          <li>Line two</li>
          <li>Line three </li>
      </ul></td>
  </tr>
</table><br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
  <tr>
    <td bgcolor="#999999"><span class="style1">Product Title Two </span></td>
    <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="#" onClick="return toggleTab(this)">Hide Product

Description</a> </span></strong></div></td>
  </tr>
</table>
<br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
  <tr>
    <td><p>Product Description</p>
        <ul>
          <li>Line one</li>
          <li>Line two</li>
          <li>Line three </li>
      </ul></td>
  </tr>
</table><br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
  <tr>
    <td bgcolor="#999999"><span class="style1">Product Title Three </span></td>
    <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="#" onClick="return toggleTab(this)">Hide Product

Description</a> </span></strong></div></td>
  </tr>
</table>
<br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
  <tr>
    <td><p>Product Description</p>
        <ul>
          <li>Line one</li>
          <li>Line two</li>
          <li>Line three </li>
      </ul></td>
  </tr>
</table>
</body>
</html>


0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
Hi,

Yeah that is kinda what I wanted to achieve but as a server side ASP.NET solution rather than a client side one, I think I should have made that more clear!! Sorry...

Carl
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
So you want on every Hide/Show link klick to open the asp with the approprite parameter and compose the appropriate page in ASP, right?
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
How about this:

<%

 descPar = Request.QueryString("desc")

%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Untitled Document</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
.style1 {
      color: #FFFFFF;
      font-weight: bold;
}
.style2 {color: #FFFFFF}
-->
</style>
</head>
<body>

<div align="right"><a href="products.asp?desc=showAll">Show All Product Descriptions</a> / <a

href="products.asp?desc=hideAll">Hide All Product Description</a> <br>
</div>
<hr>
<br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
  <tr>
    <td bgcolor="#999999"><span class="style1">Product Title One </span></td>
    <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="products.asp?desc=<%
  If(descPar<>"hideAll" AND descPar<>"hide1") Then %>hide1">Hide Product Description</a> </span></strong></div></td>
  </tr>
</table>
<br>

<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
  <tr>
    <td><p>Product Description</p>
        <ul>
          <li>Line one</li>
          <li>Line two</li>
          <li>Line three </li>
      </ul></td>
  </tr>
</table>
<% Else %>show1">Show Product Description</a> </span></strong></div></td>
  </tr>
</table>
<br>
<% End If %>

<br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
  <tr>
    <td bgcolor="#999999"><span class="style1">Product Title Two </span></td>
    <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="products.asp?desc=<%
  If(descPar<>"hideAll" AND descPar<>"hide2") Then %>hide2">Hide Product Description</a> </span></strong></div></td>
  </tr>
</table>
<br>

<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
  <tr>
    <td><p>Product Description</p>
        <ul>
          <li>Line one</li>
          <li>Line two</li>
          <li>Line three </li>
      </ul></td>
  </tr>
</table>
<% Else %>show2">Show Product Description</a> </span></strong></div></td>
  </tr>
</table>
<br>
<% End If %>

<br>
<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
  <tr>
    <td bgcolor="#999999"><span class="style1">Product Title Three </span></td>
    <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="products.asp?desc=<%
  If(descPar<>"hideAll" AND descPar<>"hide3") Then %>hide3">Hide Product Description</a> </span></strong></div></td>
  </tr>
</table>
<br>

<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
  <tr>
    <td><p>Product Description</p>
        <ul>
          <li>Line one</li>
          <li>Line two</li>
          <li>Line three </li>
      </ul></td>
  </tr>
</table>
<% Else %>show3">Show Product Description</a> </span></strong></div></td>
  </tr>
</table>
<br>
<% End If %>

<br>
</body>
</html>


0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
Basically thats right, but its all ASP.NET so the table is rendered through a ASP.NET Repeater control, not traditional asp. Which is where the tricky bit lies!!

0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
What dotNET language do you use?  VB.Net or C#
0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
VB.Net
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
I have to go home now, but I did receive today my VisualStudio Enterprise Architect and will install it tomorrow.
So your question is the first topic on my list tomorrow ;-)

See you,
Zvonko

0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
thanks for your effort so far!!
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Oh, one more thing: the Repeater control make only sense with some data source.
What is your data source?
0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
Righty, I have actually found a solution purley in asp.net which really ended up quite simple, the code for anyone interetsed is as follows:

<asp:Repeater ID=Repeater1 Runat="server">
  <ItemTemplate>
    <asp:Panel ID="Panel1" Runat="server">
      Product Description HTML Here...
    </asp:Panel>
    <br>
    <asp:LinkButton OnCommand="Button_Command" CommandName="visible" Runat="server" Text="hide" ID="Linkbutton1"></asp:LinkButton>
  </ItemTemplate>
</asp:Repeater>

code behind:

Public Sub Button_Command(ByVal s As Object, ByVal e As CommandEventArgs)
  Select Case e.CommandName
     Case "visible"
      Dim Panel1 As Panel = CType(CType(s, Control).Parent, RepeaterItem).FindControl("Panel1")
      If Panel1.Visible Then
        Panel1.Visible = False
      Else
        Panel1.Visible = True
      End If
  End Select
End Sub

Now this works great but ive descovered a new problem, because in my page I actually have a sub nested repeater inside the main repeater its creating a huge HUGE amount of view state data which means each time I click to hide a panel area the postback and page load is really slow.

Now your suggestion Zvonko is great in a way because its client side so once the page is downloaded then its done and I wouldnt have to worry about maintaining viewstate and could save on page size quite considerably.

So im trying to find a way to render the page using asp.net still but do all the hiding and showing using your javascript solution.

However I have a few problems I need to know can be solved...

1) Will your solution which u posted in ur 2nd post work if the products are rendered dynamically through asp.net, ie will it work if only 2 products are in the database and still work if at another point 60 products are in there??

2) Can the show / hide all descriptions buttons at the top work in the setup talked about in Q1)

3) The tricky one!! Imagine each product has a nested table under it rendered by a nested repeater which lists out peoples comments on the product, and then under that list there is a small form for users to add there own comment. Now we have a system like this in place at the moment so for example if we have a page with 10 products, there are also 10 sets of product comments under the description and also 10 sets of small form box's and submit buttons under the comments. The actual mechanics of all that work fine at the moment, but the way it works is in the normal ASP.NET way of posting back to itself, and also because the page is often quite long it maintains the scroll position on the page using the NFission.WebControls.ScrollKeeper module.

Now the reason im asking this question is because of the following, im worried that if for example a user has hidden some product descriptions, and then fills in one of the forms which post backs the page it is going to effectivly reset all the product descriptions to show them all because to the javascript its just the page being loaded from fresh. But I would need somehow for this system of the javascript hiding and showing product descriptions to retain its layout through the postback.

Im really rubbish with javascript so im struggling to work out a way of doing this, the only thing so far is that a hidden form field could be rendered on the page load with by default a string of 111111's with as many 1's as there are products. Then whenever a product description for say example the 3rd prduct on the page is hidden it changes the character with the index of the product (ie 3rd) to a zero so then the hidden form field would have a value of 110111'etc so we always have the layout of the page stored in the form field and then some kind of javascript can return the page layout to the config stored in that form element. Could this be done?? A bit of a challenge I know...

If this is not possible I was have to stick to the purley ASP.NET solution as this works but is just a bit greedy on page size :(

Thanks again for your help!!

Carl Southgate
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Uhf, many questions :O

Ok, first from my side, I discovered that there is no way to install IIS6.0 on Windows2000. I have to upgrade to Windows2003Server to be able to develope ASP.NET
That will take some time, so it is good that you now evaluate the JavaScript possibilities.

To avoid confusion I give some names for the three paths we walked so far.
The first one I proposed was the "pure JavaScript" proposal.
The second one was the "ASP querystring" proposal.
And you tested the "Repeater control" version.

So here my statements according to your requirments.
1.) In the ASP-QueryString solution you cannot maintain the state of form fields when they are "hidden" because they are cut away from the page. Only option would be to store the "hidden" field values in some Server Session variables (I would not recommand)
2.) In the pure-JavaScript solution there is no built in state maintanenece betwean the page reloads. Therefore you need somewhere some state storage. You have three options: Cookies, QueryString and hidden fields.

I preffee the QueryString option.

Tell me what you think.
0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
The way I would like to achieve it is by rendering the page using ASP.NET as it does at the moment, but to do the showing and hiding using the pure-JavaScript solution.

I agree on finding a way to store the state though in the JavaScript, I dont however think using a QueryString will work on the ASP.NET page though becuse in ASP.NET everything is posted back to itself using a form post so there is no way of us appending anything onto the QueryString. Thats why I suggested the hidden form field as it will be maintained through any of the asp.net post backs.

- Carl Southgate
0
Do You Know the 4 Main Threat Actor Types?

Do you know the main threat actor types? Most attackers fall into one of four categories, each with their own favored tactics, techniques, and procedures.

 
LVL 2

Author Comment

by:createnetwork
Comment Utility
To demonatrate what I mean with the postback thing, the form I have stuck round the pure-JavaScript solution will demonstrate it. asically call this lot index.htm and then hide some descriptions, click submit and u will see the layout reverts back. I need it to maintain the page layout.

Code --->

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>index.htm</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
.style1 {
     color: #FFFFFF;
     font-weight: bold;
}
.style2 {color: #FFFFFF}
-->
</style>
<script>
function toggleTab(theLink){
  theTab = theLink.parentNode;
  while(theTab && theTab.nodeName!="TABLE"){
    theTab = theTab.parentNode;
  }
  if(theLink.innerHTML.indexOf("Show")>-1){
    strFrom = "Show";
    strTo = "Hide";
    disp = "block";
  } else {
    strFrom = "Hide";
    strTo = "Show";
    disp = "none";
  }
  allTabs = document.getElementsByTagName("TABLE");
  for(i=0;i<allTabs.length;i++){
    if(theTab==null){
      if(allTabs[i].className=="prodTab"){
        tabLink = allTabs[i].rows[0].cells[1];
        tabLink.innerHTML = tabLink.innerHTML.replace(strFrom, strTo);
      }
      if(allTabs[i].className=="descTab"){
        allTabs[i].style.display = disp;
      }
    } else {
      if(allTabs[i]==theTab){
        theLink.innerHTML = theLink.innerHTML.replace(strFrom, strTo);
        allTabs[i+1].style.display = disp;
        break;
      }
    }
  }
  return false;
}
</script>
</head>
<body>
<form action="index.htm" method="post">
  <div align="right"><a href="#" onClick="return toggleTab(this)">Show All Product Descriptions</a> / <a href="#" onClick="return toggleTab(this)">Hide All Product Description</a> <br>
  </div>
  <hr>
  <br>
  <table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
    <tr>
      <td bgcolor="#999999"><span class="style1">Product Title One </span></td>
      <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="#" onClick="return toggleTab(this)">Hide Product Description</a> </span></strong></div></td>
    </tr>
  </table>
  <br>
  <table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
    <tr>
      <td><p>Product Description</p>
        <ul>
          <li>Line one</li>
          <li>Line two</li>
          <li>Line three </li>
        </ul></td>
    </tr>
  </table>
  <br>
  <table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
    <tr>
      <td bgcolor="#999999"><span class="style1">Product Title Two </span></td>
      <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="#" onClick="return toggleTab(this)">Hide Product Description</a> </span></strong></div></td>
    </tr>
  </table>
  <br>
  <table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
    <tr>
      <td><p>Product Description</p>
        <ul>
          <li>Line one</li>
          <li>Line two</li>
          <li>Line three </li>
        </ul></td>
    </tr>
  </table>
  <br>
  <table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
    <tr>
      <td bgcolor="#999999"><span class="style1">Product Title Three </span></td>
      <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="#" onClick="return toggleTab(this)">Hide Product Description</a> </span></strong></div></td>
    </tr>
  </table>
  <br>
  <table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
    <tr>
      <td><p>Product Description</p>
        <ul>
          <li>Line one</li>
          <li>Line two</li>
          <li>Line three </li>
        </ul></td>
    </tr>
  </table>
  <input name="Submit" type="submit" value="Submit">
</form>
</body>
</html>
0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
Hi again, from that list of 3 questions I asked I have answered the first two because I have an example now of your pure-JavaScript solution being rendered using a ASP.NET repeater. Here is an example, ignore the data... Im just pulling from a xml feed so I could create a quick example!!

http://www.createmail.co.uk/TestSite/RepeaterProblemExample.aspx

It works great :) Just the maintaining state over postbacks I need sorting now!! and u will have converted me to using more JavaScript in my work!!

Here is the source code of that page by the way:

<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Xml" %>
<script language="VB" runat="server">

  Sub Page_Load(sender as Object, e as EventArgs)
   
    repeater.DataSource = GetRSSFeed("http://www.aspmessageboard.com/scripts/rss.xml")
    repeater.DataBind()
            
  End Sub

  Function GetRSSFeed(strURL as String) as DataTable
 
    'Get the XML data
    Dim reader as XmlTextReader = New XmlTextReader(strURL)
   
    'return a new DataSet
    Dim ds as DataSet = New DataSet()
    ds.ReadXml(reader)    
    Return ds.Tables(2)
      
  End Function
 
</script>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>index.htm</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
.style1 {
     color: #FFFFFF;
     font-weight: bold;
}
.style2 {color: #FFFFFF}
-->
</style>
<script>
function toggleTab(theLink){
  theTab = theLink.parentNode;
  while(theTab && theTab.nodeName!="TABLE"){
    theTab = theTab.parentNode;
  }
  if(theLink.innerHTML.indexOf("Show")>-1){
    strFrom = "Show";
    strTo = "Hide";
    disp = "block";
  } else {
    strFrom = "Hide";
    strTo = "Show";
    disp = "none";
  }
  allTabs = document.getElementsByTagName("TABLE");
  for(i=0;i<allTabs.length;i++){
    if(theTab==null){
      if(allTabs[i].className=="prodTab"){
        tabLink = allTabs[i].rows[0].cells[1];
        tabLink.innerHTML = tabLink.innerHTML.replace(strFrom, strTo);
      }
      if(allTabs[i].className=="descTab"){
        allTabs[i].style.display = disp;
      }
    } else {
      if(allTabs[i]==theTab){
        theLink.innerHTML = theLink.innerHTML.replace(strFrom, strTo);
        allTabs[i+1].style.display = disp;
        break;
      }
    }
  }
  return false;
}
</script>
</head>
<body>
<form runat="server">  
  <div align="right"><a href="#" onClick="return toggleTab(this)">Show All Product Descriptions</a> / <a href="#" onClick="return toggleTab(this)">Hide All Product Description</a> <br>
  </div>
  <hr>
  <br>
  <asp:Repeater id="repeater" runat="server">
  <ItemTemplate>
  <table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
    <tr>
      <td bgcolor="#999999"><span class="style1"><%#Container.DataItem("title")%></span></td>
      <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="#" onClick="return toggleTab(this)">Hide Product Description</a> </span></strong></div></td>
    </tr>
  </table>
  <br>
  <table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
    <tr>
      <td><p>Product Description</p>
        <ul>
          <li><%#Container.DataItem("link")%></li>
          <li><%#Container.DataItem("datePosted")%></li>
          <li><%#Container.DataItem("channel_Id")%></li>
        </ul></td>
    </tr>
  </table>
  <br>
  </ItemTemplate>
  </asp:Repeater>
  <asp:Button ID="button" runat="server" Text="Postback page" />
</form>
</body>
</html>



0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Thanks for the ASP.NET example.
I will take your active page source and extend it to maintain the state on page reload by using a hidden field on the form.

0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
That would be great, I can increase the points by 5 today... Not a lot but thats all I got and the goalposts for the question have moved slightly!! hehe

- Carl Southgate
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
:-)
0
 
LVL 63

Accepted Solution

by:
Zvonko earned 415 total points
Comment Utility
Your five points offer from your daily contigent is more worth then five hundred points offer from unlimited points contigent of Premium members ;-)

Here is the new script version:
<script>
function toggleTab(theLink){
  theState = "";
  theTab = theLink.parentNode;
  while(theTab && theTab.nodeName!="TABLE"){
    theTab = theTab.parentNode;
  }
  if(theLink.innerHTML.indexOf("Show")>-1){
    strFrom = "Show";
    strTo = "Hide";
    disp = "block";
    dState = "1";
  } else {
    strFrom = "Hide";
    strTo = "Show";
    disp = "none";
    dState = "0";
  }
  allTabs = document.getElementsByTagName("TABLE");
  for(i=0;i<allTabs.length;i++){
    if(theTab==null){
      if(allTabs[i].className=="prodTab"){
        tabLink = allTabs[i].rows[0].cells[1];
        tabLink.innerHTML = tabLink.innerHTML.replace(strFrom, strTo);
      }
      if(allTabs[i].className=="descTab"){
        allTabs[i].style.display = disp;
        theState += dState;
      }
    } else {
      if(allTabs[i]==theTab){
        theLink.innerHTML = theLink.innerHTML.replace(strFrom, strTo);
        allTabs[i+1].style.display = disp;
      }
      if(allTabs[i].className=="descTab"){
        if(allTabs[i].style.display=="none"){
          theState += "0";
        } else {
          theState += "1";
        }
      }
    }
   
  }
  document.forms[0].descState.value = theState;
  return false;
}
function getDescState(){
  theState = document.forms[0].descState.value;
  strFrom = "Hide";
  strTo = "Show";
  disp = "none";
  allTabs = document.getElementsByTagName("TABLE");
  for(i=0;i<allTabs.length;i++){
    if(allTabs[i].className=="prodTab"){
      dState = theState.substr(0,1);
      theState = theState.substr(1);
      if(dState == "0"){
        tabLink = allTabs[i].rows[0].cells[1];
        tabLink.innerHTML = tabLink.innerHTML.replace(strFrom, strTo);
        allTabs[i+1].style.display = disp;
      }
    }
  }
}
</script>
</head>
<body onLoad="getDescState()">

And you need one additional hidden field:
<input type="hidden" name="descState" id="descState" value="<%=Request.Form("descState")%>">

0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
Works a treat!! I should be able to work this into my project now :) FOr anyone else who is interested in seeing the working page click here:

http://www.createmail.co.uk/TestSite/RepeaterProblemExample.aspx

Or if that page disappears here is the source code for the example:

<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Xml" %>
<script language="VB" runat="server">

  Sub Page_Load(sender as Object, e as EventArgs)
   
    repeater.DataSource = GetRSSFeed("http://www.aspmessageboard.com/scripts/rss.xml")
    repeater.DataBind()
            
  End Sub

  Function GetRSSFeed(strURL as String) as DataTable
 
    'Get the XML data
    Dim reader as XmlTextReader = New XmlTextReader(strURL)
   
    'return a new DataSet
    Dim ds as DataSet = New DataSet()
    ds.ReadXml(reader)    
    Return ds.Tables(2)
      
  End Function
 
</script>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>index.htm</title>
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<style type="text/css">
<!--
.style1 {
     color: #FFFFFF;
     font-weight: bold;
}
.style2 {color: #FFFFFF}
-->
</style>
<script>
function toggleTab(theLink){
  theState = "";
  theTab = theLink.parentNode;
  while(theTab && theTab.nodeName!="TABLE"){
    theTab = theTab.parentNode;
  }
  if(theLink.innerHTML.indexOf("Show")>-1){
    strFrom = "Show";
    strTo = "Hide";
    disp = "block";
    dState = "1";
  } else {
    strFrom = "Hide";
    strTo = "Show";
    disp = "none";
    dState = "0";
  }
  allTabs = document.getElementsByTagName("TABLE");
  for(i=0;i<allTabs.length;i++){
    if(theTab==null){
      if(allTabs[i].className=="prodTab"){
        tabLink = allTabs[i].rows[0].cells[1];
        tabLink.innerHTML = tabLink.innerHTML.replace(strFrom, strTo);
      }
      if(allTabs[i].className=="descTab"){
        allTabs[i].style.display = disp;
        theState += dState;
      }
    } else {
      if(allTabs[i]==theTab){
        theLink.innerHTML = theLink.innerHTML.replace(strFrom, strTo);
        allTabs[i+1].style.display = disp;
      }
      if(allTabs[i].className=="descTab"){
        if(allTabs[i].style.display=="none"){
          theState += "0";
        } else {
          theState += "1";
        }
      }
    }
   
  }
  document.forms[0].descState.value = theState;
  return false;
}
function getDescState(){
  theState = document.forms[0].descState.value;
  strFrom = "Hide";
  strTo = "Show";
  disp = "none";
  allTabs = document.getElementsByTagName("TABLE");
  for(i=0;i<allTabs.length;i++){
    if(allTabs[i].className=="prodTab"){
      dState = theState.substr(0,1);
      theState = theState.substr(1);
      if(dState == "0"){
        tabLink = allTabs[i].rows[0].cells[1];
        tabLink.innerHTML = tabLink.innerHTML.replace(strFrom, strTo);
        allTabs[i+1].style.display = disp;
      }
    }
  }
}
</script>
</head>
<body onLoad="getDescState()">
<form runat="server">
  <input type="hidden" name="descState" id="descState" value="<%=Request.Form("descState")%>">
  <div align="right"><a href="#" onClick="return toggleTab(this)">Show All Product Descriptions</a> / <a href="#" onClick="return toggleTab(this)">Hide All Product Description</a> <br>
  </div>
  <hr>
  <br>
  <asp:Repeater id="repeater" runat="server">
  <ItemTemplate>
  <table width="100%"  border="0" cellspacing="0" cellpadding="5" class="prodTab">
    <tr>
      <td bgcolor="#999999"><span class="style1"><%#Container.DataItem("title")%></span></td>
      <td bgcolor="#999999"><div align="right"><strong><span class="style2"><a href="#" onClick="return toggleTab(this)">Hide Product Description</a> </span></strong></div></td>
    </tr>
  </table>
  <br>
  <table width="100%"  border="0" cellspacing="0" cellpadding="5" class="descTab">
    <tr>
      <td><p>Product Description</p>
        <ul>
          <li><%#Container.DataItem("link")%></li>
          <li><%#Container.DataItem("datePosted")%></li>
          <li><%#Container.DataItem("channel_Id")%></li>
        </ul></td>
    </tr>
  </table>
  <br>
  </ItemTemplate>
  </asp:Repeater>
  <asp:Button ID="button" runat="server" Text="Postback page" />
</form>
</body>
</html>

Many thanks

Carl Southgate
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Thank you for the dot.net examples and for the feedback.

See you,
Zvonko
0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
One quick query... im integrating this into my exsisting page but the layout is far more complex and the whole lot is inside another table and it seems to mess the show all / hide all buttons...

Look at the example here:

http://www.createmail.co.uk/TestSite/RepeaterProblemExample.aspx

Where I have dropped everything inside a table...

Regards

Carl Southgate
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Ok, that was my fault. I assumed when behind the link is NO table, then it is the All link.
It is more simple to look for the All text in the link.
Like this:
function toggleTab(theLink){
  theState = "";
  theTab = theLink.parentNode;
  while(theTab && theTab.nodeName!="TABLE"){
    theTab = theTab.parentNode;
  }
  if(theLink.innerHTML.indexOf("Show")>-1){
    strFrom = "Show";
    strTo = "Hide";
    disp = "block";
    dState = "1";
  } else {
    strFrom = "Hide";
    strTo = "Show";
    disp = "none";
    dState = "0";
  }
  all = (theLink.innerHTML.indexOf("All")>-1);
  allTabs = document.getElementsByTagName("TABLE");
  for(i=0;i<allTabs.length;i++){
    if(all){
      if(allTabs[i].className=="prodTab"){
        tabLink = allTabs[i].rows[0].cells[1];
        tabLink.innerHTML = tabLink.innerHTML.replace(strFrom, strTo);
      }
      if(allTabs[i].className=="descTab"){
        allTabs[i].style.display = disp;
        theState += dState;
      }
    } else {
      if(allTabs[i]==theTab){
        theLink.innerHTML = theLink.innerHTML.replace(strFrom, strTo);
        allTabs[i+1].style.display = disp;
      }
      if(allTabs[i].className=="descTab"){
        if(allTabs[i].style.display=="none"){
          theState += "0";
        } else {
          theState += "1";
        }
      }
    }
   
  }
  document.forms[0].descState.value = theState;
  return false;
}


That should do the trick.

0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
Hmm... Ive been battling to integrate this into my page, but im having a bit of a problem getting the show/ hide all and the retaining of page state working... The page im working on is huge compared to the small example we worked on, so its going to be difficult to demonstrate...

The actual test server isnt live so I cant let u see the actual page but what I have done is let the ASP.NET render all the html output and just copied and pasted that into a static html page (tho is still has an aspx suffix but just ignore that!! the page is just html client side code)

It looks a completed mess because no style sheet of gfx but the framework of the page is there... you will see the show / hide cv links work... It just doesnt retain page state or show / hide all...

This may be something to do with the layout of the page im not sure, or it could be a silly mistake on my part...

One error im getting lots of is:

'tabLink' is null or not an object

I hope you can help cos im not so good with JavaScript!!

- Carl Southgate
0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Ok, new version.

Because of the nested tables I had now to count the links and the descTab tables.
For the links I used the class=="Col_Whi"

linkClass = "Col_Whi";
tableClass = "descTab";
function toggleTab(theLink){
  theState = "";
  if(theLink.innerHTML.indexOf("Show")>-1){
    strFrom = "Show";
    strTo = "Hide";
    disp = "block";
    dState = "1";
  } else {
    strFrom = "Hide";
    strTo = "Show";
    disp = "none";
    dState = "0";
  }
  allTabs = document.getElementsByTagName("TABLE");
  allLinks = document.links;
  all = (theLink.innerHTML.indexOf("All")>-1);
  linkN = -1;
  for(i=0;i<allLinks.length;i++){
    if(allLinks[i].className==linkClass){
      linkN++;
      if(all || allLinks[i]==theLink){
        allLinks[i].innerHTML = allLinks[i].innerHTML.replace(strFrom, strTo);
      }
      if(allLinks[i]==theLink) descN = linkN;
    }
  }
  linkN = descN;
  descN = -1;
  for(i=0;i<allTabs.length;i++){
    if(allTabs[i].className==tableClass){
      descN++;
      if(all || descN==linkN){
        allTabs[i].style.display = disp;
      }
      if(allTabs[i].style.display=="none"){
        theState += "0";
      } else {
        theState += "1";
      }
    }
  }
  document.forms[0].descState.value = theState;
  return false;
}

function getDescState(){
  theState = document.forms[0].descState.value;
  strFrom = "Hide";
  strTo = "Show";
  disp = "none";
  allLinks = document.links;
  allTabs = document.getElementsByTagName("TABLE");
  for(i=0;i<allLinks.length;i++){
    if(allLinks[i].className==linkClass){
      dState = theState.substr(0,1);
      theState = theState.substr(1);
      if(dState == "0"){
        allLinks[i].innerHTML = allLinks[i].innerHTML.replace(strFrom, strTo);
      }
    }
  }
  theState = document.forms[0].descState.value;
  for(i=0;i<allTabs.length;i++){
    if(allTabs[i].className==tableClass){
      dState = theState.substr(0,1);
      theState = theState.substr(1);
      if(dState == "0"){
        allTabs[i].style.display = disp;
      }
    }
  }
}


0
 
LVL 2

Author Comment

by:createnetwork
Comment Utility
Brilliant!! Thats working a treat... only one minor last bug, but I think this must be something dead easy to fix...

If you look at the example on this page, again the static html rendered from my ASP.NET page you can see that everything works... Except if you click one of the show all / hide all buttons first... Then it throws an error, but if you then click and individual hide button... then go back to the hide all they work!!

This the last thing I promise!! hehe

http://www.createmail.co.uk/TestSite/RepeaterProblemExample2.aspx

Thanks

Carl
0
 
LVL 63

Expert Comment

by:Zvonko
Comment Utility
Uhps, you are right. It was a sily not tested situation.
Please add after this line:
  linkN = -1;

Add this default setting:
  descN = -1;

0

Featured Post

Better Security Awareness With Threat Intelligence

See how one of the leading financial services organizations uses Recorded Future as part of a holistic threat intelligence program to promote security awareness and proactively and efficiently identify threats.

Join & Write a Comment

I have helped a lot of people on EE with their coding sources and have enjoyed near about every minute of it. Sometimes it can get a little tedious but it is always a challenge and the one thing that I always say is:  The Exchange of information …
Have you ever needed to get an ASP script to wait for a while? I have, just to let something else happen. Or in my case, to allow other stuff to happen while I was murdering my MySQL database with an update. The Original Issue This was written…
This demo shows you how to set up the containerized NetScaler CPX with NetScaler Management and Analytics System in a non-routable Mesos/Marathon environment for use with Micro-Services applications.
Polish reports in Access so they look terrific. Take yourself to another level. Equations, Back Color, Alternate Back Color. Write easy VBA Code. Tighten space to use less pages. Launch report from a menu, considering criteria only when it is filled…

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now