Link to home
Start Free TrialLog in
Avatar of Brian
BrianFlag for United States of America

asked on

Nested GridViews

Hello Experts,

I need to display a GridView Control that will list something like the following below and beileve I need to use nested GridViews. As you will see below not every ghaoc_id has a value for p_id. 10 = Eat Well for Life in the ghaoc_id field and 200 = Online Only in the p_id field and each of those values have multiple dates below. I need to have users order a course and I need to pass the ghaoc_id and p_id values from GridView Button/Link Control to insert into a DB. But before I have those values inserted I need to display the Course Name (ghaoc_id) and Related Programs (p_id) along with all schedule dates. As you will see below not every Course Name has a Related Program. As of now if I retrieve all data into one GridView it does not separate the Programs it runs them all together. Any ideas how I can separate the data nicely along with adding a GridView Button/Link to pass those to values?

COURSE SCHEDULE TABLE:
csch_id    ghaoc_id    p_id    date
1              10              200     10/5/2011
2              10              200     10/12/2011
3              10              208     10/6/2011
4              10              208     10/9/2011
6              11              205     11/8/2011
7              11              205     11/19/2011
8              11              205     11/28/2011
9              14              NULL  11/3/2011
10            14              NULL  11/5/2011
Avatar of SAMIR BHOGAYTA
SAMIR BHOGAYTA
Flag of India image

Hello, this is the example for your solution

http://www.codeproject.com/KB/aspnet/SkinSample.aspx
Avatar of Brian

ASKER

@ramkisan,

Your link no longer works :(
Avatar of Brian

ASKER

@ramkisan & samirbhogayta,

Ok, after looking at both of your examples I'm now wondering if I don't need a nested GridView and would like you both to see the sample data that I'm retriving to just one GridView Control now and mayber you all will have a different approach for me.

I'm attaching a .txt file with my sample data and a description as to what I need the data to look like.

ee.txt
Avatar of Brian

ASKER

Is anyone able to still help with this post?
ASKER CERTIFIED SOLUTION
Avatar of Carlos Villegas
Carlos Villegas
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Also I have omitted the p_id parameter in the schedule link because your data don't fit in your UI grouping logic... or may be I don't understand very well what you want...
Important!!! your data must be sorted first by CourseName, otherwise the grouping logic that I have implemented will be broken.
Avatar of Brian

ASKER

@yv989c,

My HERO!!! That worked EXACLTY as I need it to look. The only thing is that the "schedule" link needs to pass ghaoc_id & p_id. The reason I need to pass to is because ghaoc_id is referrenced as the Course Name and p_id is referrenced as the Program Name related to Course Name but NOT every ghaoc_id will have a p_id so for the Courses that don't have a Program Name I just need to display ghaoc_id to the "schedule" link.

Now how hard would it be if you walk me through putting that into ADO.NET logic? I will create the logic if you don't mind proofreading it to make it work like what you just did by binding the DataTable with typed data.
Hello buddy, first, ghaoc_id = CourseName ok? and you want ghaoc_id and p_id to be present in the link as parameters... but your example data don't match 1=1, I mean, see bellow, ghaoc_id=10 has p_id=200 or 208... what p_id value do you want in the link? maybe your data is wrong?

csch_id    ghaoc_id    p_id    date
1              10              200     10/5/2011
2              10              200     10/12/2011
3              10              208     10/6/2011
4              10              208     10/9/2011
6              11              205     11/8/2011
7              11              205     11/19/2011
8              11              205     11/28/2011
9              14              NULL  11/3/2011
10            14              NULL  11/5/2011
Avatar of Brian

ASKER

For the following below the link would include ghaoc_id & p_id like schedule.aspx?ghaoc_id=10&p_id=200

1              10              200     10/5/2011
2              10              200     10/12/2011

For the following below the link would include ghaoc_id & p_id like schedule.aspx?ghaoc_id=10&p_id=NULL. Then what I plan on doing later is adding those values ghaoc_id and p_id even if p_id is NULL to another table called PurchasedCourses that would contain that data. When a user query that table and sees ghaoc_id = 10 and p_id = NULL they know to place the order for just ghaoc_id which is Eat Well for Life I. If there where a value for p_id then they would place na order for Eat Well for Life I - Live & Online.

I know it may seem odd and I have tried telling them that this is not a good practice because I would like there to be a Program for EVERY Course but for now is not but in future there will be. So this will be future proof but for now some Courses will NOT always have a Program name until they are developed later on this year.

Below I created what you did in ADO.NET but not sure how to add the Column Name like you did. I'm stuck in between the line of code below.

if (dtt != null)
                {
                    DataRow data = dtt.Rows[0];
                }


protected void RetrieveCoursesPrograms()
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["HealthCourses"].ConnectionString))
        {
            SqlCommand cmd = new SqlCommand();
            cmd.CommandText = "TEST1";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Connection = conn;

            DataTable dtt = new DataTable();
            SqlDataAdapter adp = new SqlDataAdapter();

            try
            {
                conn.Open();

                adp.SelectCommand = cmd;
                adp.Fill(dtt);

                if (dtt != null)
                {
                    DataRow data = dtt.Rows[0];
                }

                myRepeater.DataSource = dtt;
                myRepeater.DataBind();
            }

            catch (Exception ex)
            {
                ex.Message.ToString();
            }

            finally
            {
                conn.Close();
            }
        }
    }

Open in new window

Hello, you don't need a DataTable (I use that for demo purposes), just use the DataReader instance:
protected void RetrieveCoursesPrograms()
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["HealthCourses"].ConnectionString))
        {
            SqlCommand cmd = new SqlCommand();
            cmd.CommandText = "TEST1";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Connection = conn;

            try
            {
                conn.Open();
                myRepeater.DataSource = cm.ExecuteReader();
                myRepeater.DataBind();
            }

            catch (Exception ex)
            {
                ex.Message.ToString();
            }

            finally
            {
                conn.Close();
            }
        }
    }

Open in new window

And when you said:
how to add the Column Name like you did
What column name?
Avatar of Brian

ASKER

Ok, I changed it to DataReader like you mentioned. Please see code below. Please see the HTML and CODEBEHIND below. When I run the page I get the following error message below.

Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: CS0103: The name 'lastProgramName' does not exist in the current context

Source Error:

 

Line 55:             <ItemTemplate>
Line 56:                 <asp:PlaceHolder ID="PlaceHolder1" runat="server" Visible='<%# lastProgramName != Eval("CourseName").ToString() %>'>
Line 57:                     <asp:PlaceHolder ID="PlaceHolder2" runat="server" Visible='<%# lastProgramName != null %>'>
Line 58:                         <tr>
Line 59:                             <td colspan="4">
 

CODEBEHIND:

    protected void RetrieveCoursesPrograms()
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["HealthCourses"].ConnectionString))
        {
            int ghaoc_id = Convert.ToInt32(Request.QueryString["ghaoc_id"]);

            SqlCommand cmd = new SqlCommand();
            cmd.CommandText = "TEST2";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Connection = conn;

            cmd.Parameters.AddWithValue("@ghaoc_id", SqlDbType.Int).Value = ghaoc_id;

            try
            {
                conn.Open();
                myRepeater.DataSource = cmd.ExecuteReader();
                myRepeater.DataBind();
            }

            catch (Exception ex)
            {
                ex.Message.ToString();
            }

            finally
            {
                conn.Close();
            }
        }
    }

Open in new window

<asp:Repeater runat="server" ID="myRepeater">
            <ItemTemplate>
                <asp:PlaceHolder ID="PlaceHolder1" runat="server" Visible='<%# lastProgramName != Eval("CourseName").ToString() %>'>
                    <asp:PlaceHolder ID="PlaceHolder2" runat="server" Visible='<%# lastProgramName != null %>'>
                        <tr>
                            <td colspan="4">
                                <hr />
                            </td>
                        </tr>
                    </asp:PlaceHolder>
                    <tr>
                        <td colspan="2" style="font-weight: bold;">
                            <%# lastProgramName = Eval("ghaocp_name").ToString()%>
                        </td>
                        <td colspan="2" style="text-align: center;">
                            <asp:HyperLink ID="HyperLink1" NavigateUrl='<%# "Schedule.aspx?ghaoc_id=" + Eval("ghaoc_id") %>'
                                runat="server" Text="Schedule" />
                        </td>
                    </tr>
                </asp:PlaceHolder>
                <tr>
                    <td>
                        <%# Convert.ToDateTime(Eval("csch_startdate")).ToLongDateString()%>
                    </td>
                    <td>
                        <%# Eval("hmi_name")%>
                    </td>
                    <td>
                        <%# Convert.ToDateTime(Eval("csch_starttime")).ToShortTimeString()%>
                    </td>
                    <td>
                        <%# Convert.ToDateTime(Eval("csch_endtime")).ToShortTimeString()%>
                    </td>
                </tr>
            </ItemTemplate>
        </asp:Repeater>

Open in new window

Hello, did you forgotten declare this in your page class?
    // To control the group separator logic
    string lastProgramName = null;

Open in new window


That is in my example, look carefully.
Avatar of Brian

ASKER

No, I tried it with and without before my last post. I added it again and receive the error below.

Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

Compiler Error Message: CS0122: 'programinfo_ghap_one_index.lastProgramName' is inaccessible due to its protection level

Source Error:

 

Line 55:             <ItemTemplate>
Line 56:                 <asp:PlaceHolder ID="PlaceHolder1" runat="server" Visible='<%# lastProgramName != Eval("CourseName").ToString() %>'>
Line 57:                     <asp:PlaceHolder ID="PlaceHolder2" runat="server" Visible='<%# lastProgramName != null %>'>
Line 58:                         <tr>
Line 59:                             <td colspan="4">
 

Source File: c:\inetpub\wwwroot\WellnessSite\programinfo\ghap\one\index.aspx    Line: 57
Ok, try:
protected string lastProgramName = null;

Open in new window

Or simply:
public string lastProgramName = null;

Open in new window

Avatar of Brian

ASKER

Ok, that worked. I then ran the page again and received a different error with the HyperLink Control.

<asp:HyperLink ID="HyperLink1" NavigateUrl='<%# "Schedule.aspx?ghaoc_id=" + Eval("ghaoc_id") %>'
                                runat="server" Text="Schedule" />


DataBinding: 'System.Data.Common.DataRecordInternal' does not contain a property with the name 'ghaoc_id'.
Ok that error means that your query dont return a column named ghaoc_id

Now be sure that wherever I use Eval("COLUMN_NAME") match your query column names returned by your SP.
Avatar of Brian

ASKER

yv989c,

I have happy tears. That worked after adding the ghaoc_id..

Now three more questions:

1.) how can I add ghaocp_id to the HyperLink Control? I would like to have both ghaoc_id and ghaocp_id to the same HyperLink Control.

2.) how can I format the data in the Repeater to look like your sample. Right now ALL the data is ran together. Please see screenshot.



3.) This is the biggest problem of the two. If I would select a Course Name and that Course has the value NULL assigned to ghaocp_id then nothing is displayed. I still need to display the other data except for ghaocp_name since it's obviously not there.

Please see my updated HTML Markup and CODEBEHIND below.

 User generated image
CODEBEHIND:

public string lastProgramName = null;

    protected void RetrieveCoursesPrograms()
    {
        using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["HealthCourses"].ConnectionString))
        {
            int ghaoc_id = Convert.ToInt32(Request.QueryString["ghaoc_id"]);

            SqlCommand cmd = new SqlCommand();
            cmd.CommandText = "TEST2";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.Connection = conn;

            cmd.Parameters.AddWithValue("@ghaoc_id", SqlDbType.Int).Value = ghaoc_id;

            try
            {
                conn.Open();
                myRepeater.DataSource = cmd.ExecuteReader();
                myRepeater.DataBind();
            }

            catch (Exception ex)
            {
                ex.Message.ToString();
            }

            finally
            {
                conn.Close();
            }
        }
    }

Open in new window

HTML MARKUP:

<asp:Repeater runat="server" ID="myRepeater">
            <ItemTemplate>
                <asp:PlaceHolder ID="PlaceHolder1" runat="server" Visible='<%# lastProgramName != Eval("ghaocp_name").ToString() %>'>
                    <asp:PlaceHolder ID="PlaceHolder2" runat="server" Visible='<%# lastProgramName != null %>'>
                        <tr>
                            <td colspan="4">
                                <hr />
                            </td>
                        </tr>
                    </asp:PlaceHolder>
                    <tr>
                        <td colspan="2" style="font-weight: bold;">
                            <%# lastProgramName = Eval("ghaocp_name").ToString()%>
                        </td>
                        <td colspan="2" style="text-align: center;">
                            <asp:HyperLink ID="HyperLink1" NavigateUrl='<%# "Schedule.aspx?ghaoc_id=" + Eval("ghaoc_id") %>'
                                runat="server" Text="Schedule" />
                        </td>
                    </tr>
                </asp:PlaceHolder>
                <tr>
                    <td>
                        <%# Convert.ToDateTime(Eval("csch_startdate")).ToLongDateString()%>
                    </td>
                    <td>
                        <%# Eval("hmi_name").ToString()%>
                    </td>
                    <td>
                        <%# Eval("csch_starttime").ToString()%>
                    </td>
                    <td>
                        <%# Eval("csch_endtime").ToString()%>
                    </td>
                </tr>
            </ItemTemplate>
        </asp:Repeater>

Open in new window

Avatar of Brian

ASKER

The following value ghaocp_name is reference to a Program Name if one happens to be related to a Course which could be why I'm not getting Course Name to display of Program name below does not exist.

<asp:PlaceHolder ID="PlaceHolder1" runat="server" Visible='<%# lastProgramName != Eval("ghaocp_name").ToString() %>'>
About your question #2, did you put the Repeater control inside the table tag?
<table style="width: 600px;">
    <asp:Repeater runat="server" ID="myRepeater">
    </asp:Repeater>
</table>

I will see your other question later, I'm going to lunch...
Avatar of Brian

ASKER

Hi yv989c,

The above worked perfectly fine for the formatting. Ok, I really appreciate your help!!! Let me know when you have time to help me out with Questions 1 and 3. Thanks again yv989c....
Avatar of Brian

ASKER

Hi yv989c,

Are you still able to help!
Hello asp_net2, I have been busy:
1.) how can I add ghaocp_id to the HyperLink Control? I would like to have both ghaoc_id and ghaocp_id to the same HyperLink Control.
Change:
<asp:HyperLink ID="HyperLink1" NavigateUrl='<%# "Schedule.aspx?ghaoc_id=" + Eval("ghaoc_id") %>' runat="server" Text="Schedule" />

Open in new window

With:
<asp:HyperLink ID="HyperLink1" NavigateUrl='<%# "Schedule.aspx?ghaoc_id=" + Eval("ghaoc_id") + "&ghaocp_id=" + Eval("ghaocp_id") %>' runat="server" Text="Schedule" />

Open in new window



3.) This is the biggest problem of the two. If I would select a Course Name and that Course has the value NULL assigned to ghaocp_id then nothing is displayed. I still need to display the other data except for ghaocp_name since it's obviously not there.
Please explain a little more this point, can you give me an example?
Avatar of Brian

ASKER

Hi yv989c,

First of all, thank you very much, I GREATLY appreciate ALL your help. This is the last part to the problems I was having. The HyperLink worked as needed. Thank you for that!!! I will explain the best I can. Please see the attached excel file, I thought this would be better rather than adding the Table Schema and Sample Data below and have it loose it's formating.

You will see in the Excel file that I have 10 rows of data that have NULL values for the ghaocp_id field. That means that there are NO Course Programs for that particular Course which is the ghaoc_id field. So if I have NULL values for ghaocp_id then I still need to display the rest of the data for that Course which would be the Instructor, start date, start time, end time. If a Course has a Program(s) then display the data you are already helping me out with.

Thank you again!!!
EE.xls
Ohh I see, BTW the var lastProgramName has a wrong mean, lastProgramName must be called lastCourseName, but the name dont matter, what really matter is the value that you are giving to it, you only need to change this line:
<%# lastProgramName = Eval("ghaocp_name").ToString()%>

Open in new window

With:
<%# lastProgramName = Eval("THE COLUMN THAT CONTAIN YOUR COURSE NAME").ToString()%>

Open in new window


I'm right?
Avatar of Brian

ASKER

Hi yv989c,

No, that did not work. Please see the screenshots that i"m attaching. The first screen shot will display all data related to Eat Well for Life I which has multiple programs.

The second screenshot will NOT SHOW any data if you select Drop 10 in 10 because Drop 10 in 10 DOES NOT have any programs associate to it, BUT it still has the same data that needs displayed even though it does not have a program associated to it. So in other words I still need to display the same data with or without programs assocaited to Courses.

Now, I just executed the attached stored procedure labeled TEST2 which is the stored procedure that is called to retrieve the data and NOTHING gets displayed if I enter value 308 for ghaoc_id which is related to Drop 10 in 10. I need it to display all data for this value and other even though it DOES NOT have a program associate to it. All Courses that DO NOT have programs assocaited to it are stored as NULL values for the ghaocp_id field.
 User generated image User generated image
We are getting yv989c, I can feel it. Just have to overcome this last hurdle :( Thanks again for your continued help, I truly appreciate it, this project is a very big project that I'm involved in and this part has been frustrating me the most :(
TEST2 STORED PROCEDURE

ALTER PROCEDURE [dbo].[TEST2]

(
@ghaoc_id int
)

AS

SELECT cs.ghaoc_id, oc.ghaco_name, cs.ghaocp_id, cs.csch_startdate, cs.csch_starttime, cs.csch_endtime, hi.hmi_name, p.ghaocp_name
FROM HealthCourses_CourseSchedules AS cs
INNER JOIN HealthCourses_HighmarkInstructors AS hi
ON cs.hmi_id = hi.hmi_id
INNER JOIN HealthCourses_GeneralHealthAwarenessOneCoursesPrograms AS p
ON cs.ghaocp_id = p.ghaocp_id
INNER JOIN HealthCourses_GeneralHealthAwarenessOneCourses AS oc
ON cs.ghaoc_id = oc.ghaoc_id
WHERE cs.ghaoc_id = @ghaoc_id
ORDER BY ghaocp_name ASC

Open in new window

SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Brian

ASKER

Hi yv989c,

THANK YOU!!!! Everything works PERFECT!!!! That change in SQL Worked Perfectly... Thank you so much for helping me out with this yv989c, I can't thank you enough for sticking around and helping me out from start to finish. A true .NET Jedi Knight :)

I would like to change the HyperLink Control to a LinkButton Control but keeping the NavigateURL info and use that on the LinkButton Control. Let me know if you would be interested, if so the link is below. Please let me know once you recieve this so I can close this post.

https://www.experts-exchange.com/questions/27387210/HyperLink-Format.html
Glad to help buddy, also I have posted in your other question the changes required to make it a LinkButton, can I ask what do you plan to do when an user click on that LinkButton?
Avatar of Brian

ASKER

Hi yv989c,

Thank you again, I truly appreciate ALL your help from start to finish with both of the posts.

I also used the HyperLink Control rather than the LinkButton after all. I was able to make the HyperLink look like a button using CSS. It looks fine but thank you for the help with the LinkButton post anyway.

As for my plans with the HyperLink, I plan on passing those two values to another page that will then be used to add those two values into another table called Health_EnrolledUsers. I plan on directing a user to a login page first before those two values can be added because I need the users employee ID to be collected first so that when I add those two values I know who those values belong to.

I wanted the user to first login before they can schedule but I was told to show the users what courses are offered and then they can schedule if they like what is offered. So that being the case I need to first check on the page that the HyperLink is taking them to to see if there employee ID exists which I plan on storing that into a session. So if their employee ID exist then they can submit. If employeeID does not exist then have user login and then transfer back to that page.
Avatar of Brian

ASKER

Let me know if I'm handling the passing of the values before I insert them.
Hello, that is fine, but what do you meant with:
Let me know if I'm handling the passing of the values before I insert them.
Sorry I don't understand that...
Avatar of Brian

ASKER

Sorry, I started getting very sleepy when I was writing that :) I wanted your opinion of how I was handling the passing of values based on employee ID. I'll break down what I need to do since everything is displayed nicely. I have NO PROBLEM creating another post for this and provide you the URL to it if you would like me to do that I will.

Step1: User selects Course/Program and clicks on Schedule Link/Button. The link will take them to Schedule.aspx passing two parameters ghaoc_id and ghaocp_id. ghaoc_id will ALWAYS have a value but ghaocp_id as you already know may not. If the value for ghaocp_id is NULL then the value is emptly/blank in the URL.

Step2: Schedule.aspx page will check to see if employee ID Session exists. If so, then provide information about user and display the Course Name/ Program before they click on Submit button which will add data into DB. If employee ID Session DOES NOT exist then redirect to login page/create account. Once user either creates an account or logs in then they will get redirect back to schedule.aspx to view/submit there information.

Does that sound ok to do yv989c or would you change this process and if so how and why?
What you describes is a good design, my recommendation is this:
1. To accomplish that you must use Forms Authentication.
2. The page that display the courses must has public access.
3. The page Schedule.aspx must be accessible only to authenticated users, so when you reach this page forms authentication will take care of this, redirecting the user to a login page, when the user have successfully logged in, then you can use the method FormsAuthentication.RedirectFromLoginPage to redirect the user to the page that required authentication (it will go back to Schedule.aspx with the right parameters).
4. On Schedule.aspx, you can implement in the page Load event the logic to retrieve the EmployeeId from your DB by using the name of the authenticated user (this.User.Identity.Name), that is my advice without using session objects.
Avatar of Brian

ASKER

Hi yv989c,

Sorry for the delay. I was out of the office for a day. I don't want to turn this into another post because that would not be fair to you so, I will be brief and will possilbly be opening another post today or tomorrow about this if you want to follow me I would appreciate it since you are familiar with my design and requirements.

I understand everything you said but not sure why you are using (this.User.Identiy.Name) rather than checking agains Session.
Ok buddy, sure, I will help you when I have the time.
Avatar of Brian

ASKER

ok, thank you. No hurry, whenever you have time. I hopiong to post that later today or possible tomorrow.

Thanks again...
Avatar of Brian

ASKER

yv989c:

Once again, thank you for your Time, Patience, Willing to help others, and your Knowledge. I can't thank you enough for helping me out with this post from start to finish. It's a scruggle sometimes when you have to where multiple hats and are asked to do things in a relatively short period of time. THANK YOU AGAIN......
Thank you for those words, as always, I'm glad to have been of help.