Solved

For Each Loop - Create Table

Posted on 2013-12-16
13
690 Views
Last Modified: 2013-12-24
Hello Experts,

I have an asp.net menu I'm currently using.  It is built using a for each loop pulling items from a dataset.  I'd like to remove the menu and just add tables for each of the possible menu headers.  That way I have a table for each laid out horizontally.  That gives my users an exposed list if possible items instead of them hovering over each header to see what items are available.  I need some help populating a panel with these tables.  I've tried a few things but I'm unable to recreate what I currently use to achieve this.  

My data looks like this:

MenuHeader     MenuChildName
"Header1"         "dog"
"Header1"         "cat"
"Header2"         "bird"
"Header3"         "fish"

The loop I use to populate the asp.net menu:

Dim item As MenuItem = Nothing

            item = Menu1.FindItem(row("MenuHeadername").ToString)
            If (item Is Nothing) Then
                item = New MenuItem(row("MenuHeadername").ToString)
                item.Selectable = False
                item.ChildItems.Add(New MenuItem(row("MenuName").ToString, row("reportname")))
                Menu1.Items.Add(item)
            Else
                item.ChildItems.Add(New MenuItem(row("MenuName").ToString, row("reportname")))
            End If
            Next

Open in new window


So far I've come up with this:

For Each row As DataRow In dsMenuItems.Tables("catalog").Rows
                Dim tblHeaderRow, tblRow As TableRow
                Dim tblHeaderCell, tblCell As TableCell
                Dim output As New Web.UI.WebControls.Table

                tblHeaderRow = pnlMenu.FindControl(row("menuheadername"))
                
                'Create the header row
                If tblHeaderRow Is Nothing Then
                    tblHeaderRow = New TableHeaderRow
                    tblHeaderCell = New TableHeaderCell
                    tblHeaderCell.Text = row("menuheadername")
                    tblHeaderRow.Cells.Add(tblHeaderCell)
                    output.Rows.Add(tblHeaderRow)
                    pnlMenu.Controls.Add(output)
                Else
                    tblRow = New TableRow
                    tblCell = New TableCell
                    tblCell.Text = row("menuname")
                    tblRow.Cells.Add(tblCell)
                    output.Rows.Add(tblRow)
                End If
            Next

Open in new window


This gives me 1 table and it repeats the menuheadername for each child item instead of listing the child items.  How do I programatically create these tables for each of my menuheadernames and list their child menunames properly?
0
Comment
Question by:jay-are
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 7
  • 6
13 Comments
 
LVL 15

Expert Comment

by:Ess Kay
ID: 39721902
just add a subheader with the child names listed
         tblHeaderRow = pnlMenu.FindControl(row("menuheadername"))
               
                'Create the header row



                If tblHeaderRow Is Nothing Then
                    tblHeaderRow = New TableHeaderRow
                    tblHeaderCell = New TableHeaderCell
                    tblHeaderCell.Text = row("menuheadername")
                    tblHeaderRow.Cells.Add(tblHeaderCell)
                    output.Rows.Add(tblHeaderRow)
                    pnlMenu.Controls.Add(output)
                Else
                    tblRow = New TableRow
                    tblCell = New TableCell
                    tblCell.Text = row("menuname")
                    tblRow.Cells.Add(tblCell)
                    output.Rows.Add(tblRow)
                End If
if child found then ....
loop through children
item.ChildItems.Add(New MenuItem(row("MenuName").ToString, row("reportname")))
0
 

Author Comment

by:jay-are
ID: 39721930
I was trying to do that with this part of the code:

 Else
                    tblRow = New TableRow
                    tblCell = New TableCell
                    tblCell.Text = row("menuname")
                    tblRow.Cells.Add(tblCell)
                    output.Rows.Add(tblRow)

Open in new window


The first step of what I have is to find the table headers to see if they exist, if not then create a new table with that menuheadername.  If it does exist then add rows to the existing table with the menunames as the cells.
0
 
LVL 15

Expert Comment

by:Ess Kay
ID: 39724259
i thought its called

MenuChildName
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 

Author Comment

by:jay-are
ID: 39724372
The actual name of the field is MenuName.  The tables I'm trying to create should look like:

Table Header:  MenuHeadername
Table Row(s):   MenuName

I want a table for each of the MenuHeaderNames in the dataset.  I just can't get the loop to create a table for each of the headers.  It also doesn't list the MenuNames at all.
0
 
LVL 15

Expert Comment

by:Ess Kay
ID: 39724780
why not put them in one table like you described before

MenuHeader     MenuChildName
"Header1"         "dog"
"Header1"         "cat"
"Header2"         "bird"
"Header3"         "fish"

you want separate tables like

table1
"Header1"        
"Header2"        
"Header3"        

table2
"dog"
"cat"
"bird"
 "fish"
0
 

Author Comment

by:jay-are
ID: 39724794
I'm trying to get a table layout like this:

Header1    Header2    Header3
dog               bird           fish
cat

I just want a horizontal layout of all possible items.  If it is one table that would be fine I think.
0
 
LVL 15

Expert Comment

by:Ess Kay
ID: 39724804
in the else statement, you dont have this line

 pnlMenu.Controls.Add(output)
0
 

Author Comment

by:jay-are
ID: 39724815
Correct, I don't.  Adding it doesn't make a difference since the for each loop I'm using isn't the right way of doing this.  I still get one table and only the MenuHeaderName listed for each occurance of a menuitem.  Looks like:

Header1
Header1
Header2
Header3

The loops itself needs to be redone, I'm just not sure how to do this properly.
0
 
LVL 15

Expert Comment

by:Ess Kay
ID: 39724857
you can deffinately get away with it if you use LINQ

http://msdn.microsoft.com/en-us/vstudio/bb688088.aspx




The specific select functions are here:
http://msdn.microsoft.com/en-us/vstudio/bb737936


you need to do a query to look something  like the following

dim dt1 as datatable = select distinct headername from yourtable
dim dt2 as datatable
for each row in dt1
    dt2 = select menuname from yourtable where headername = dt1.columns(0).cells(0).value

    for each menu in dt2
        --add to column
    end
end
    add row
0
 
LVL 15

Expert Comment

by:Ess Kay
ID: 39724865
0
 

Author Comment

by:jay-are
ID: 39727607
I'm pretty sure I can use a simple loop to handle this, I'm just not smart enough to figure it out.  I keep getting repeat MenuHeaderNames.  I assume my code:

tblHeaderRow = pnlMenu.FindControl(row("menuheadername").ToString())

Open in new window


wasn't working.  So I tried adding a table id each time through the loop.  Now I know it is working because I get this error:

Multiple controls with the same ID 'tblTheName' were found.  FindControl requires that controls have unique IDs.

So how do I fix my loop so it is only adding 1 table per unique menuheadername?  Currently my If statement doesn't seem to work...

If Not dsMenuItems.Tables("catalog").Rows.Count = 0 Then

            For Each row As DataRow In dsMenuItems.Tables("catalog").Rows
                Dim tblHeaderRow, tblRow As TableRow
                Dim tblHeaderCell, tblCell As TableCell
                Dim output As New Web.UI.WebControls.Table

                tblHeaderRow = pnlMenu.FindControl(row("menuheadername").ToString())

                If (tblHeaderRow Is Nothing) Then

                    tblHeaderRow = New TableHeaderRow
                    tblHeaderCell = New TableHeaderCell
                    tblHeaderCell.Text = row("menuheadername")
                    tblHeaderRow.Cells.Add(tblHeaderCell)
                    output.ID = "tbl" & row("menuheadername")
                    output.Rows.Add(tblHeaderRow)
                    tblRow = New TableRow
                    tblCell = New TableCell
                    tblCell.Text = row("menuname")
                    tblRow.Cells.Add(tblCell)
                    output.Rows.Add(tblRow)

                Else

                    tblRow = New TableRow
                    tblCell = New TableCell
                    tblCell.Text = row("menuname")
                    tblRow.Cells.Add(tblCell)
                    output.Rows.Add(tblRow)
                End If

                pnlMenu.Controls.Add(output)
            Next
        End If

Open in new window

0
 

Accepted Solution

by:
jay-are earned 0 total points
ID: 39729747
Ok this was tricky to do but I got some help and got this to work.  I added an asp.net table to my existing panel and added 1 row with two cells.  The first cell is just a static cell I'll use for non-menu items.  The second cell contains all the possible menu items.  The code to populate the tables is:

If Not dsMenuItems.Tables("catalog").Rows.Count = 0 Then
            Dim tblHeaderRow As TableRow = Nothing
            Dim tblRow As TableRow = Nothing
            Dim tblHeaderCell As TableCell = Nothing
            Dim tblCell As TableCell = Nothing
            Dim output As New Table
            Dim ParentTable As New Table
            Dim strMenuHeaderName As String = dsMenuItems.Tables("catalog").Rows(0).Item("menuheadername").ToString()
            Dim lbl As New Label
            Dim lc As New LiteralControl
            ParentTable.Rows.Add(New TableRow)

            tblHeaderRow = New TableHeaderRow
            tblHeaderCell = New TableHeaderCell
            output = New Table
            tblHeaderCell.Text = dsMenuItems.Tables("catalog").Rows(0).Item("menuheadername").ToString()
            tblHeaderRow.Cells.Add(tblHeaderCell)
            output.ID = "tbl" & dsMenuItems.Tables("catalog").Rows(0).Item("menuheadername").ToString()
            output.Rows.Add(tblHeaderRow)
            For Each row As DataRow In dsMenuItems.Tables("catalog").Rows
                If strMenuHeaderName <> row("menuheadername") Then
                    strMenuHeaderName = row("menuheadername")
                    tblCell = New TableCell
                    tblCell.CssClass = "cellMenuCSS"
                    ParentTable.Rows(0).Cells.Add(tblCell)
                    ParentTable.Rows(0).Cells(ParentTable.Rows(0).Cells.Count - 1).Controls.Add(output)
                    'pnlMenu.Controls.Add(output)
                    tblHeaderRow = New TableHeaderRow
                    tblHeaderCell = New TableHeaderCell
                    output = New Table
                    tblHeaderCell.Text = row("menuheadername")
                    tblHeaderRow.Cells.Add(tblHeaderCell)
                    output.ID = "tbl" & row("menuheadername")
                    output.Rows.Add(tblHeaderRow)
                End If
                tblRow = New TableRow
                tblCell = New TableCell
                lc = New LiteralControl
                lc.Text = "<span onclick=""lblClick('" & row("reportname") & "');""> " & row("menuname") & "</span>"
                tblCell.Controls.Add(lc)
                tblRow.Cells.Add(tblCell)
                output.Rows.Add(tblRow)
            Next
            tblCell = New TableCell
            ParentTable.Rows(0).Cells.Add(tblCell)
            ParentTable.Rows(0).Cells(ParentTable.Rows(0).Cells.Count - 1).Controls.Add(output)
            cellMenu.Controls.Add(ParentTable)
        End If

Open in new window


This creates a table for each of the menuheadernames and adds the menuname as a row to the correct table.  The output table is then added to a 'parent table' which is added to the cell I have already setup in the asp table.  I also added a literal control so I could click on the menunames and use that event.  Now I just have to get the css done properly...
0
 

Author Closing Comment

by:jay-are
ID: 39737636
Was able to get this working on my own.  My solution does exactly what I asked for in my question.
0

Featured Post

Instantly Create Instructional Tutorials

Contextual Guidance at the moment of need helps your employees adopt to new software or processes instantly. Boost knowledge retention and employee engagement step-by-step with one easy solution.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Creating an analog clock UserControl seems fairly straight forward.  It is, after all, essentially just a circle with several lines in it!  Two common approaches for rendering an analog clock typically involve either manually calculating points with…
User art_snob (http://www.experts-exchange.com/M_6114203.html) encountered strange behavior of Android Web browser on his Mobile Web site. It took a while to find the true cause. It happens so, that the Android Web browser (at least up to OS ver. 2.…
Michael from AdRem Software explains how to view the most utilized and worst performing nodes in your network, by accessing the Top Charts view in NetCrunch network monitor (https://www.adremsoft.com/). Top Charts is a view in which you can set seve…
In this video you will find out how to export Office 365 mailboxes using the built in eDiscovery tool. Bear in mind that although this method might be useful in some cases, using PST files as Office 365 backup is troublesome in a long run (more on t…
Suggested Courses

617 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