Home > database >  How do I dynamically create, and populate a Table (DataTable?)
How do I dynamically create, and populate a Table (DataTable?)

Time:07-15

The Issue I am currently facing is, I would like Keep the HMTL Table Structure I currently have, if at all possible.I would like tp dynamically create this table instead of doing so at the HTML level. I would Like to do so dynamically at the data level. Originally I had created a table via the ASPX page, and then I realized that I would have to go back and dynamically add in new revised row changes. This got ugly really quickly. my plan was to traverse each row in the table until i found the place I wanted to add a new row of data, but then I realized that it would mess up the columns to the right of the data, causing unwanted gaps if I added anything in the first 2 columns. I tried this code originally:

 For Each row As HtmlTableRow In tblDates.Rows
           For Each col As HtmlTableCell In tblDates.Columns
                   If col.ID = "lblSubmittedToESO" Then

                        tblDates.InnerHtml  = "<tr> "
                        tblDates.InnerHtml  = "<td> <asp:Label ID='lblSubmittedToESO' runat='server' Text='Date Site Plan Submitted to ESO for Approval: '></asp:Label></td>"
                        tblDates.InnerHtml  = ""
                        tblDates.InnerHtml  = ""
                        tblDates.InnerHtml  = "</tr>"

                    End If
                Next
            Next 

However, as you already know.. this did not work as there was no such thing as "tblDates.Columns". The original structure of my table is as follows:


<table id="tblDates" runat ="server" border="1">
            <tr id ="tblDatesHeader">
                <td>
                </td>
                <td align="center">
                    <asp:Label ID="lblDate" runat="server" Text="Date" Font-Bold="true"></asp:Label>
                    <br />
                    <asp:Label ID="lblDateFormat" runat="server" Text="(MM/DD/YYYY)" Font-Bold="true"></asp:Label>
                </td>
                <td colspan="2" align="center">
                    <asp:Label ID="lblNumOfDays" runat="server" Text="Number of Days to Complete Action"
                        Font-Bold="true"></asp:Label>
                </td>
            </tr>
            <tr id ="ECOSubmitRow">
                <td>
                    <asp:Label ID="lblSubmittedToECO" runat="server" Text="Date Site Plan Submitted to ECO for Approval: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtSubmittedToECO" runat="server"></asp:TextBox>
                </td>
                <td>
                    <asp:Label ID="lblPMO" runat="server" Text="PWO: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtPMO" runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr id ="ECOSignedRow">
                <td>
                    <asp:Label ID="lblSignedByECO" runat="server" Text="Date Site Plan Signed by ECO: "></asp:Label>&nbsp; <img src="img/help_bubble.gif" id="helpbubble5" alt="" />
                </td>
                <td>
                    <asp:TextBox ID="txtSignedByECO" runat="server"></asp:TextBox>
                </td>
                <td>
                    <asp:Label ID="lblECO" runat="server" Text="ESO: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtECO" runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr id ="PMOSubmitRow">
                <td>
                    <asp:Label ID="lblSubmittedToPMO" runat="server" Text="Date Site Plan Submitted to PMO for Approval: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtSubmittedToPMO" runat="server"></asp:TextBox>
                </td>
                <td>
                    <asp:Label ID="lblPMOECO" runat="server" Text="PMO/ECO sign to EED/MSC: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtPMOECO" runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr id ="PMOSignedRow">
                <td>
                    <asp:Label ID="lblSignedByPMO" runat="server" Text="Date Site Plan Signed by PMO: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtSignedByPMO" runat="server"></asp:TextBox>
                </td>
                <td>
                    <asp:Label ID="lblEED" runat="server" Text="EED/MSC: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtEED" runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr id ="EEDSubmitRow">
                <td>
                    <asp:Label ID="lblSubmittedToEED" runat="server" Text="Date Plan Submitted to EED for Endorsement: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtSubmittedToEED" runat="server"></asp:TextBox>
                </td>
                <td>
                    <asp:Label ID="lblABA" runat="server" Text="ABA: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtABA" runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr id ="EEDEndorcedRow">
                <td>
                    <asp:Label ID="lblEndorsedByEED" runat="server" Text="Date Endorsed by EED/MSC and Forwarded to ABA: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtEndorsedByEED" runat="server"></asp:TextBox>
                </td>
                <td>
                    <asp:Label ID="lblOverallCycle" runat="server" Text="Project Overall Cycle Time: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtOverallCycle" runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr id ="ActionRow">
                <td>
                    <asp:Label ID="lblABAaction" runat="server" Text="Date of ABA Action (Endorsement/Approval/Return): "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtABAaction" runat="server"></asp:TextBox>
                </td>
            </tr>
             <tr id ="InitDateRow">
                <td>
                    <asp:Label ID="lblABAAAIInitDate" runat="server" Text="Inititial Date AAI was Issued: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtInitAAIDate" runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr id ="AAISubmitRow">
                <td>
                    <asp:Label ID="lblAAISubmitted" runat="server" Text="Date Request  Information Submitted: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtFIDate" runat="server"></asp:TextBox>
                </td>
                <td>
                    <asp:Label ID="lblFIDays" runat="server" Text="RFI Overall Days: "></asp:Label>
                </td>
                <td>
                    <asp:TextBox ID="txtRFITotal" runat="server"></asp:TextBox>
                </td>
            </tr>
            <tr>
                <td>
                </td>
                <td>
                </td>
            </tr>
            <tr>
                <td>
                </td>
                <td>
                </td>
                <td>
                </td>
                <td>
                </td>
            </tr>
            <tr align="center">
                <td colspan="2">
                    <asp:Label ID="lblRating" runat="server" Text="Rating (see note):" Font-Bold="true"></asp:Label>
                </td>
                <td>
                    <asp:Label ID="lblEEDEval" runat="server" Text="FEC or MCSC<br>Evaluation<br>Score: 0-100"
                        Font-Bold="true" Width="200px"></asp:Label>
                </td>
                <td>
                    <asp:Label ID="lblSSAEval" runat="server" Text="SSA<br>Evaluation<br>Score: 0-100"
                        Font-Bold="true"></asp:Label>
                </td>
            </tr>
            <tr align="center">
                <td colspan="2">
                    <asp:Label ID="lblOverall" runat="server" Text="Overall Score From Evaluation on Next Page:"></asp:Label>
                </td>
                <td align="center">
                    <asp:TextBox ID="txtFECOverall" runat="server" Width="40px"></asp:TextBox>
                </td>
                <td align="center">
                    <asp:TextBox ID="txtNossaOverall" runat="server" Width="40px"></asp:TextBox>
                </td>
            </tr>
        </table>

So right now I have 4 stored procedures that pull dates for 4 different process. what I would like to is dynamically create this table and add the dates that I have already pulled and stored into objects and place them in this table in their specific position. Originally once I pulled the date I just added them in by referencing the "ID" of the . Normally it would be just adding a datasource and populating the table with that once source, but I would also like to design the layout. Attached to this question is a link for image to show what it looks like when I orginally created it. However, Now I would like to build it dynamically. enter image description here

Note careful:

We did not write loops to load up the HTML.

We use the ado.net data table to get the data. And THEN SEND that data table to the HTML system to display.

Note how we NOT directly working with the HMTL - since well, it is JUST HTML, and as NO business try to be a data system for us - but is great for display!

So, in above, we have a add new button at the top. That could allow us to add a new row to the data base. But, once again, we would add the new row, and then AGAIN send that data (and our new row) to the Gridview, but AGAIN we don't write HTML, we don't try to modify the HTML, and we still have 100% data operations.

Now, no question we might need some markup to edit a single row. That markup to edit ONE row can then be used for our "edit" button, and even our add new button.

So, markup can be used for data entery, but for display of the table and data? That goes and belongs in the database.

So, in above, we might below the grid, drop in some markup that allows edit of one row.

Say, like this:

<div id="EditRecord" runat="server" style="float:left;display: normal" clientidmode="Static"  >
    <style>
        .iForm label {display:inline-block;width:90px}
        .iForm input {border-radius:8px;border-width:1px;margin-bottom:10px}                
        .iForm textarea {border-radius:8px;border-width:1px;margin-bottom:10px}     
        .iForm input[type=checkbox] {margin-right:8px}
    </style>

    <div style="float:left" >
            <label>HotelName</label><asp:TextBox ID="txtHotel" runat="server" f="HOtelName" width="280"></asp:TextBox> <br />
            <label>First Name</label><asp:TextBox ID="tFN" runat="server" f="FirstName" Width="140"></asp:TextBox> <br />
            <label>Last Name</label><asp:TextBox ID="tLN" runat="server" f="LastName" Width="140"></asp:TextBox> <br />
            <label>City</label><asp:TextBox ID="tCity" runat="server" f="City" Width="140"></asp:TextBox> <br />
            <label>Province</label><asp:TextBox ID="tProvince" runat="server" f="Province" Width="75"></asp:TextBox> <br />
    </div>
    <div style="float:left;margin-left:20px" >
        <label>Description</label> <br />
        <asp:TextBox ID="txtNotes" runat="server" Width="400" TextMode="MultiLine" 
            Height="150px" f="Description" ></asp:TextBox> <br />
        <asp:CheckBox ID="chkActive" f="Active" Text=" Active" runat="server" TextAlign="Right" />
        <asp:CheckBox ID="chkBalcony" f="Balcony" Text=" Has Balcony" runat="server" TextAlign="Right" />
    </div>
    <div style="clear:both"></div>
    <button id="cmdSave" runat="server"  onserverclick="cmdSave_ServerClick" >
        <span aria-hidden="true" > Save</span> 
    </button>

    <button id="cmdCancel" runat="server"  style="margin-left:15px"
        onserverclick="cmdCancel_ServerClick"
        >
        <span aria-hidden="true" > Back/Cancel</span>
    </button>

    <button id="cmdDelete" runat="server"  style="margin-left:15px">
        <span aria-hidden="true" > Delete</span>
    </button>
</div>

So, that is some markup, and then we have tht button click for each row.

Our code for that click can look like this:

Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)

    Dim btn As Button = sender
    Dim gRow As GridViewRow = btn.NamingContainer
    Dim pkID = GHotels.DataKeys(gRow.RowIndex).Item("ID")

    Dim cmdSQL As New SqlCommand("SELECT * from tblHotelsA where ID = @ID")
    cmdSQL.Parameters.Add("@ID", SqlDbType.Int).Value = pkID
    Dim rstData As DataTable = MyrstP(cmdSQL)

    Call fLoader(Me.EditRecord, rstData.Rows(0)) ' load up hidden div with data
    ' hide grid
    MyGrid.Style.Add("display", "none")
    EditRecord.Style.Add("display", "normal")
    ViewState("rstData") = rstData

End Sub

Again, note how we do data operations against the database - NOT the HTML table!!! - we certainly did use the "UI" and row click of the grid to get that one row to work on, but after that we RIGHT BACK to useing datatable, and data operations against the database and NOT AGAINST the HTML markup.

So, when you click on a row, we get the row "PK" data id, pull the data, load up some controls on the page, hide the grid, show the "div" that has above. We now get this:

enter image description here

Now, this post is already a bit long, and I could post more code. So, in above, the save button would:

Send data back to database (again, database - not touch the grid view or "table"

Then we re-load the grid view from database

Then we hide our div to edit, and show the div with the grid view to display any edits we made.

this code:

Protected Sub cmdSave_ServerClick(sender As Object, e As EventArgs)

    Dim rstData As DataTable = ViewState("rstData")
    Call fWriterW(EditRecord, rstData.Rows(0))  ' div to table
    Call SaveTable(rstData, "tblHotelsA")  ' send table back to database

    LoadGrid()    ' refresh grid
    MyGrid.Style.Add("display", "normal")
    EditRecord.Style.Add("display", "none")

End Sub

So, the FIRST question we have and need to know here?

Where is your data now, how do you plan to load read this data. This is the first step, and worry about some HTML markup to display that data actually is the easy part - but the source and getting that data - now that's the important part of this question and process.

I should note that I come from a ms-access, VB6, FoxPro background (desktop). So, you note the above style of code - looks a lot like VBA due to my roots. But, I did make build a few helper routines used above, (like fLoader, fWirter) that makes such code easy to write.

So, your first issue? Where does the data come from now, and have you setup a valid connection and means to pull that data into a "data table", of which we THEN can send to the browser as HTML.

Edit -- I see you note that you have 4 store procedures. So yes then you can pull that data to a datatable, and then send that datatable to a GridView or say a listview.

In fact, given your existing markup, then I would suggest a listview. As noted, I often use the wizard to build the listview (or gridview). I then blow out (delete) the sql data source that the wizard creates, and as noted, removed the extra templates.

So, you have a table layout that would work quite well as a ListView.

So, taking your existing markup, say this:

It will look somthing like this:

    <div style="width:60%;padding:25px">
        <asp:ListView ID="ListView1" runat="server" DataKeyNames="ID"  >
         <LayoutTemplate>
            <table id="itemPlaceholderContainer" runat="server" border="0"  >
                <tr runat="server" style="">
                    <th runat="server">Site Plan</th>
                    <th runat="server" style="text-align:center">Date<br />(MM/DD/YYYY)</th>
                    <th runat="server" colspan="2">Number of Days to Complete Action</th>
                    <th runat="server">PWO</th>
                </tr>
                <tr id="itemPlaceholder" runat="server">
                </tr>
            </table>
            </LayoutTemplate>

     <ItemTemplate>
        <tr id ="ECOSubmitRow">
            <td>
                <asp:Label ID="lblSubmittedToECO" runat="server" Text="Site Plan Submitted to ECO for Approval: "></asp:Label>
            </td>
            <td>
                <asp:Label ID="PlanDate" runat="server" Text="MM/DD/YYYY"></asp:Label>
            </td>
            <td>
                <asp:Label ID="lblPMO" runat="server" Text="PWO: "></asp:Label>
            </td>
            <td>
                <asp:TextBox ID="txtPMO" runat="server"></asp:TextBox>
            </td>
        </tr>
       </ItemTemplate>
   </asp:ListView>

So, we have kind of this now:

enter image description here

and in fact, for the actual data, we only need ONE row.

so, looking at this, note how I suggested a list view.

I don't have your data - so, I can't really do a lot in a simple post on SO but lets re-create the first hotel grid, but using the List view.

Note how the layout is "very" simular to a table.

So, for the Hotel grid, using a ListView, then we have this:

        <asp:ListView ID="ListView1" runat="server" DataKeyNames="ID"  >
            <LayoutTemplate>
                <table id="itemPlaceholderContainer" runat="server" border="0" >
                    <tr runat="server" style="">
                        <th runat="server">FirstName</th>
                        <th runat="server">LastName</th>
                        <th runat="server">HotelName</th>
                        <th runat="server">Active</th>
                        <th runat="server">Description</th>
                    </tr>
                    <tr id="itemPlaceholder" runat="server">
                    </tr>
                </table>
            </LayoutTemplate>

            <ItemTemplate>
                <tr style="">
                    <td><asp:Label ID="FirstNameLabel" runat="server" Text='<%# Eval("FirstName") %>' /></td>
                    <td><asp:Label ID="LastNameLabel" runat="server" Text='<%# Eval("LastName") %>' /></td>
                    <td><asp:Label ID="HotelNameLabel" runat="server" Text='<%# Eval("HotelName") %>' /></td>
                    <td style="text-align:center">
                        <asp:CheckBox ID="ActiveCheckBox" runat="server" Checked='<%# Eval("Active") %>'  />
                    </td>
                    <td><asp:Label ID="DescriptionLabel" runat="server" Text='<%# Eval("Description") %>' /></td>
                </tr>
            </ItemTemplate>
        </asp:ListView>

Note again, VERY simular to a HTML table, but we use ListView, since it is like GridView a data bound control. And we can then feed it that data table.

So, my code to load this list view, is this:

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    If Not IsPostBack Then
        LoadGrid
    End If
End Sub


Sub LoadGrid()

    Dim cmdSQL = New SqlCommand("SELECT * FROM tblHotelsA ORDER BY HotelName")
    Dim rstData As DataTable
    rstData = MyrstP(cmdSQL)

    ListView1.DataSource = rstData
    ListView1.DataBind()

End Sub

And I get this:

enter image description here

So, while the GridView is "quick and dirty" as you layout becomes a little more complex, then ListView becomes a better choice - and its layout VERY much follows a HTML table, but the big deal is of course that you can feed it a data table - so, we don't try to create the HTML table or markup - we setup a layout, and feed it that data table.

  • Related