tucson
asked on
Gridview - Add/remove rows on the fly without a database
I have a gridview created blank on the fly. At the end of every row, there's an Add/Remove link button that will add/remove rows. I have one textbox field they have to enter.
As they add new rows, the text they have entered in previous rows has to be displayed. Although I see this text (in debug mode), I can't display it in the table as I loop through the gridviewrow.
The error is: "Type of value has a mismatch with column type"
Thanks
As they add new rows, the text they have entered in previous rows has to be displayed. Although I see this text (in debug mode), I can't display it in the table as I loop through the gridviewrow.
The error is: "Type of value has a mismatch with column type"
Thanks
Here's the sub that builds a blank gridview with one row:
Private Sub BuildUploadTable()
Dim dt As New DataTable
Dim dc As New DataColumn("description")
dtFiles.Columns.Add(dc)
Dim dr As DataRow = dtFiles.NewRow
dr("description") = "None"
dtFiles.Rows.Add(dr)
dsFiles.Tables.Add(dtFiles)
'gFiles.DataSource = dsFiles
gvFiles.DataSource = dtFiles
gvFiles.DataBind()
gvFiles.Visible = True
End Sub
Here's the part that's problematic:
Protected Sub gvFiles_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gvFiles.RowCommand
If dtFiles.Rows.Count = 0 Then
dtFiles.Columns.Add("tbDesc", GetType(TextBox))
dtFiles.Columns.Add("Add", GetType(ButtonColumn))
dtFiles.Columns.Add("Remove", GetType(ButtonColumn))
End If
'Convert datagrid to dt
Dim gr As GridViewRow
Dim nr As DataRow
For Each gr In gvFiles.Rows
nr = dtFiles.NewRow
'BEGIN PROBLEM
nr(0) = CType(gr.FindControl("tbDesc"), TextBox).Text
nr(1) = "Add"
nr(2) = "Remove"
'END PROBLEM
dtFiles.Rows.Add(nr)
Next
If e.CommandName = "Add" Then
'Add new row to dt
nr = dtFiles.NewRow
dtFiles.Rows.Add(nr)
dsFiles.Tables.Add(dtFiles)
gvFiles.DataSource = dtFiles
gvFiles.DataBind()
gvFiles.Visible = True
ElseIf e.CommandName = "Remove" Then
dtFiles.Rows.RemoveAt(gvFiles.Rows(e.CommandArgument).RowIndex)
dsFiles.Tables.Add(dtFiles)
gvFiles.DataSource = dtFiles
gvFiles.DataBind()
gvFiles.Visible = True
End If
End Sub
ASKER
I added and removed rows successfully in the sample code above. The problem is displaying the previous row contents when a new row is added. I can see the textbox value in the table and dataset in debug mode but can't assign those values back into the gridview to be displayed.
If you are correctly re-binding the GridView to the DataTable after adding a row, I don't see why it shouldn't work as expected.
Bob
Bob
ASKER
Please look at my code snippet. I can see the values in the dataset and datatable but once I rebind it, it's not in the gridview. Thanks.
I did look at your code, and I was trying to say that there is some missing bit of information to show why you are having a problem, because the code doesn't show it.
Bob
Bob
ASKER
EnableViewState is True for the gridview.
I'm not sure what else to look for (what "missing bit"?) It doesn't show what?
I'm not sure what else to look for (what "missing bit"?) It doesn't show what?
ASKER
It seems like my problem is that I'm trying to store the fileupload and textbox objects into the gridview AS WELL AS trying to store the string values of the fileupload and the textbox contents. And I can't do that? When I preview the datatable, the objects are in there but the values can't be displayed because the gridview also needs to display the objects.
I tried a placeholder but it doesn't work either.
I tried a placeholder but it doesn't work either.
Are you saying that you have a TemplateField defined with a FileUpload control and a TextBox in the same template?
Bob
Bob
ASKER
No they are 2 in different template columns. But I want to display the fileupload and textbox objects and their perviously entered values each time a new blank row is added.
In this example: http://geekswithblogs.net/casualjim/archive/2006/05/04/77151.aspx, you keep the fileupload/textbox objects in the footer row and adds the records into the gridview rows as labels. I want every row to be like the footer row in this example. I may just decide to to the footer row method since I'm not sure if what I'm trying to accomplish can be done in a gridview.
In this example: http://geekswithblogs.net/casualjim/archive/2006/05/04/77151.aspx, you keep the fileupload/textbox objects in the footer row and adds the records into the gridview rows as labels. I want every row to be like the footer row in this example. I may just decide to to the footer row method since I'm not sure if what I'm trying to accomplish can be done in a gridview.
How do you define your columns? Through the designer? In code?
You can't do this:
dtFiles.Columns.Add("Add", GetType(ButtonColumn))
dtFiles.Columns.Add("Remov e", GetType(ButtonColumn))
And, then this:
nr(1) = "Add"
nr(2) = "Remove"
The type is not string, so you would need to add a ButtonColumn object. I don't think that is what you meant to do.
Bob
You can't do this:
dtFiles.Columns.Add("Add",
dtFiles.Columns.Add("Remov
And, then this:
nr(1) = "Add"
nr(2) = "Remove"
The type is not string, so you would need to add a ButtonColumn object. I don't think that is what you meant to do.
Bob
ASKER
I added the columns through the designer.
The code below displays the blank rows with the appropriate controls when I added a new row.
The problem is that I can't display the values that were entered in the previous row as they add new rows. Every row is blank. The datatable and gridview only store the controls and can't display the values.
In the example below, I can't do:
nr(0) = fileU.FileName
nr(1) = tb.text, which is what I want to do.
The code below displays the blank rows with the appropriate controls when I added a new row.
The problem is that I can't display the values that were entered in the previous row as they add new rows. Every row is blank. The datatable and gridview only store the controls and can't display the values.
In the example below, I can't do:
nr(0) = fileU.FileName
nr(1) = tb.text, which is what I want to do.
For Each gr In gFiles.Rows
nr = dtFiles.NewRow
fileU = CType(gr.FindControl("FileToUpload"), FileUpload)
tb = CType(gr.FindControl("tbDesc"), TextBox)
bAdd = CType(gr.FindControl("btnAdd"), LinkButton)
nr(0) = fileU
nr(1) = tb
nr(2) = bAdd
dtFiles.Rows.Add(nr)
Next
gFiles.DataSource = dtFiles
gFiles.DataBind()
So, you want a dynamic number of file uploads, instead of a fixed number of rows (the usual way of doing business)?
Bob
Bob
ASKER
Yes, because the range of number of uploads varies from 1 to 30.
Does the <Add> button just insert a new row to upload? After you upload are you keeping track of the file name?
Bob
Bob
ASKER
The upload will occur as a batch, at the very end.
Yes, the Add button adds an empty row. I need to keep track of all the previous rows already entered before finally doing a batch upload.
Yes, the Add button adds an empty row. I need to keep track of all the previous rows already entered before finally doing a batch upload.
Attached is my version of a dynamic uploader page.
Bob
Bob
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="DynamicUploader.aspx.vb"
Inherits="DynamicUploader" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>Untitled Page</title>
<style type="text/css">
body { font-family: Tahoma; font-size: 10pt; }
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:GridView ID="GridView1" runat="server" Height="50%" Width="100%" AutoGenerateColumns="False"
Font-Names="Tahoma" Font-Size="10pt" OnRowCommand="GridView1_RowCommand" OnRowDataBound="GridView1_RowDataBound">
<Columns>
<asp:TemplateField HeaderText="Upload">
<ItemTemplate>
<asp:FileUpload ID="FileUpload" runat="server" Font-Names="Tahoma" Font-Size="10pt"
Width="100%" />
<asp:TextBox ID="FileName" runat="server" Width="100%" Visible="false" Text='<%# Eval("FileName") %>'></asp:TextBox>
</ItemTemplate>
<HeaderStyle Width="30%" />
</asp:TemplateField>
<asp:BoundField DataField="Description" HeaderText="Description">
<HeaderStyle Width="40%" />
</asp:BoundField>
<asp:ButtonField CommandName="Add" Text="Add">
<HeaderStyle Width="5%" />
</asp:ButtonField>
</Columns>
</asp:GridView>
</div>
</form>
</body>
</html>
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Thanks, I'm looking into this after lunch.
ASKER
You are indeed a genius. Thank you for taking the time. You put the fileupload and a textbox in the same template column and hide/unhide the textbox. The textbox is used to store the filename for displaying it further.
Thanks
Thanks
ASKER
I didn't expect to have the code provided to me at all. Initially his responses were vague ("missing things," "should work"). But at the end it's very clear. I will try to modify his code so that users can still browse to get their files even after a new row is inserted, perhaps create my own FileUpload subclass.
ASKER
Sorry to open this ticket again. When I upload the files at the end, what's the best way to read/write the files to upload them to the server? Since the upload control is no longer there (just the path is stored in a textbox), I can't call FileUpload.SaveAs method.
Thanks
Thanks
Bob