So I've got a gridview bound to a SQL datasource stored procedure. The stored procedure returns a pivot table, where a number of columns are unknown until run time. I therefore need to autogenerate the columns.
The gridview is intended to allow Excel-like data updates. So the goal is to have the grid load as textboxes. I know if I were to declare the columns on my aspx page, I could create template columns and handle their visibility that way.
So I believe I need a way to programmatically set all the columns to template fields (without knowing the column names), or I need to discover the method by which I can just "flip the switch" and just make everything editable.
Thanks in advance!
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSourceExcelGridTest">
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSourceExcelGridTest" runat="server" ConnectionString="<%$ ConnectionStrings:WebAppsConnectionString %>" SelectCommand="spJobForecastingGetEmployeesByDepartmentAndProject_v1" SelectCommandType="StoredProcedure" UpdateCommand="spJobForecastingUpdateHours" UpdateCommandType="StoredProcedure">
<SelectParameters>
<asp:Parameter Name="DepartmentNumber" Type="String" DefaultValue="13211" />
<asp:Parameter Name="ProjectNumber" Type="String" DefaultValue="13211" />
<asp:Parameter Name="startDate" Type="DateTime" DefaultValue="2/21/2014" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="DepartmentNumber" Type="String" />
<asp:Parameter Name="ProjectNumber" Type="String" />
<asp:Parameter Name="Alias" Type="String" />
<asp:Parameter Name="WorkWeek" Type="DateTime" />
<asp:Parameter Name="WorkHours" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
try this:
UPDATED CODE
<asp:GridView ID="GridView1" runat="server" DataSourceID="SqlDataSourceExcelGridTest">
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSourceExcelGridTest" runat="server" ConnectionString="<%$ ConnectionStrings:WebAppsConnectionString %>" SelectCommand="spJobForecastingGetEmployeesByDepartmentAndProject_v1" SelectCommandType="StoredProcedure" UpdateCommand="spJobForecastingUpdateHours" UpdateCommandType="StoredProcedure">
<SelectParameters>
<asp:Textbox ID="DepartmentNumber" DefaultValue="13211" text='<%# Eval("DepartmentNumber") %>'></asp:TextBox>
<asp:Textbox ID="ProjectNumber" Type="String" DefaultValue="13211" Text='<%# Eval("ProjectNumber") %>'></asp:TextBox>
<asp:Textbox ID="startDate" Type="DateTime" DefaultValue="2/21/2014" Text='<%# Eval("startDate") %>'></asp:TextBox>
</SelectParameters>
<UpdateParameters>
<asp:Textbox ID="DepartmentNumber" Type="String" text='<%# Eval("DepartmentNumber") %>'></asp:TextBox>
<asp:Textbox ID="ProjectNumber" Type="String" text='<%# Eval("ProjectNumber") %>'></asp:TextBox>
<asp:Textbox ID="Alias" Type="String" text='<%# Eval("Alias") %>'></asp:TextBox>
<asp:Textbox ID="WorkWeek" Type="DateTime" text='<%# Eval("WorkWeek") %>'></asp:TextBox>
<asp:Textbox ID="WorkHours" Type="Int32" text='<%# Eval("WorkHours") %>'></asp:TextBox>
</UpdateParameters>
</asp:SqlDataSource>
Related
I need help to understand the proper way to map or associate TemplateFields to the ObjectDataSource. I show only one (of many) template definitions here:
<asp:TemplateField HeaderText="First Name" SortExpression="cFIRSTNAME">
<ItemTemplate>
<asp:Label ID="lblValFirstName" runat="server" Text='<%# Eval("cFIRSTNAME") %>' style="font-weight: bold;" ></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="txtFirstName" runat="server" Text='<%# Bind("cFIRSTNAME") %>' MaxLength="20"></asp:TextBox>
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox ID="txtFirstName" runat="server" Text='<%# Bind("cFIRSTNAME") %>' MaxLength="20"></asp:TextBox>
</InsertItemTemplate>
</asp:TemplateField>
The ObjectDataSource and update parameters are:
<asp:ObjectDataSource ID="ODS_LOGIN_DETAILS" runat="server"
SelectMethod="GetLOGINSbyLoginID"
TypeName="bllLOGINS"
DeleteMethod="DeleteFromDetailsView"
InsertMethod="InsertFromDetailsView"
UpdateMethod="UpdateFromDetailsView" OldValuesParameterFormatString="original_{0}"> <UpdateParameters>
<asp:Parameter Name="p_UID_LOGIN" Type="Int32" />
<asp:Parameter Name="p_UID_CONTACT" Type="Int32" />
<asp:Parameter Name="p_UID_USER_TYPE" Type="Int32" />
<asp:Parameter Name="p_TXT_USERNAME" Type="String" />
<asp:Parameter Name="p_TXT_PASSWORD" Type="String" />
<asp:Parameter Name="p_BOOL_IS_ACTIVE" Type="Boolean" />
<asp:Parameter Name="p_DT_END" Type="DateTime" />
<asp:Parameter Name="p_FirstName" Type="String" />
<asp:Parameter Name="p_LastName" Type="String" />
<asp:Parameter Name="p_CONTACTTITLE" Type="String" />
<asp:Parameter Name="p_TXT_PHONE" Type="String" />
<asp:Parameter Name="p_CONTACT_EMAIL" Type="String" /> </UpdateParameters>
What is NOT clear to me is how is the mapping made from the templatefield textbox (txtFirstName) to the UpdateParameter "p_FirstName"?
In the existing code I am working with, I see the ObjectDataSource_Updating()-event that does a series of DVW.FindControl() values being assigned/set to the
e.InputParameter("param-name") = text-box-value
Questions?
Is this done in either the ObjectDataSource_Updating()-event or in the DetailsView_Updtaing()-event -or- by declaration aspx code?
or how?
What is the best way to do this?
Would naming the textbox-ID and the parameter-name simplify the code?
I am assuming the solutions offered would be "similar" or the same as with SqlDataSource -- please confirm?
Thanks in advance...John
I had a similar problem and was unsure how to map the textbox to the params as was getting NULL param value passed when doing a SQL trace. In the end I set the parameter name to match the value in the Text attribute bind which worked.
<UpdateParameters>
<asp:Parameter Name="my_field" Type="String" Direction="Input" />
...
<asp:TextBox Text='<%# Bind("my_field") %>'...
(I found the way it's supposed to be done as shown in my Answer below.
I'm editing my question and deleting the code I initially put here, which was a mess, leaving just the definitions).
Win7, ASP4.5, empty_web_app in VS2013 with C#. Recreated in a very simple project accessing two tables:
1st table "Students"
student_ID
student_name
student_course_ID (is Forign Key)
2nd table "Courses"
course_ID
course_name
In my web page I have DetailView1 showing details of student who's student_ID is taken from txbStudent_ID.
DetailView1 has Edit Delete and New.
When in UPDATE or INSERT mode I need to show the course_name (rather then the course ID) in a drop-down-list and update/insert accordingly.
No code behind.
My answer below is applicable to GRIDVIEW as well.
Gadi
I was so wrong they way I coded my aspx.
So here is the right way to do it, for future beginners like I am now...
(with the help of https://msdn.microsoft.com/en-us/library/ms178294(v=vs.140).aspx)
<asp:Label ID="Label1" runat="server" Text="Student_ID"></asp:Label>
<asp:TextBox ID="txbStudent_ID" runat="server"></asp:TextBox>
<br />
<asp:DetailsView ID="DetailsView1" runat="server" AutoGenerateRows="False" DataKeyNames="student_ID" DataSourceID="SqlDataSource1" Height="50px" Width="125px">
<Fields>
<asp:BoundField DataField="student_ID" HeaderText="student_ID" InsertVisible="False" ReadOnly="True" SortExpression="student_ID" />
<asp:BoundField DataField="student_name" HeaderText="student_name" SortExpression="student_name" />
<asp:TemplateField HeaderText="student_course_ID" SortExpression="student_course_ID">
<EditItemTemplate>
<asp:DropDownList
ID="DropDownList1"
runat="server"
DataSourceID="SqlDataSource2"
DataTextField="course_name"
DataValueField="course_ID"
SelectedValue='<%# Bind("student_course_ID") %>'>
</asp:DropDownList>
</EditItemTemplate>
<InsertItemTemplate>
<asp:DropDownList
ID="DropDownList2"
runat="server"
DataSourceID="SqlDataSource2"
DataTextField="course_name"
DataValueField="course_ID"
SelectedValue='<%# Bind("student_course_ID") %>'>
</asp:DropDownList>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label
ID="Label1"
runat="server"
Text='<%# Bind("student_course_ID") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="True" ShowInsertButton="True" ShowDeleteButton="True" />
</Fields>
</asp:DetailsView>
<asp:SqlDataSource
ID="SqlDataSource1"
runat="server"
ConnectionString="<%$ ConnectionStrings:Course_Student_Connection %>"
InsertCommand="INSERT INTO [Students] ([student_name], [student_course_ID]) VALUES (#student_name, #student_course_ID)"
SelectCommand="SELECT * FROM [Students] WHERE ([student_ID] = #student_ID)"
UpdateCommand="UPDATE [Students] SET [student_name] = #student_name, [student_course_ID] = #student_course_ID WHERE [student_ID] = #student_ID"
DeleteCommand="DELETE FROM [Students] WHERE [student_ID] = #student_ID">
<DeleteParameters>
<asp:Parameter Name="student_ID" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="student_name" Type="String" />
<asp:Parameter Name="student_course_ID" Type="Int32" />
</InsertParameters>
<SelectParameters>
<asp:ControlParameter ControlID="txbStudent_ID" Name="student_ID" PropertyName="Text" Type="Int32" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="student_name" Type="String" />
<asp:Parameter Name="student_course_ID" Type="Int32" />
<asp:Parameter Name="student_ID" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
<asp:SqlDataSource
ID="SqlDataSource2"
runat="server"
ConnectionString="<%$ ConnectionStrings:Course_Student_Connection %>"
SelectCommand="SELECT [course_ID], [course_name] FROM [Courses]">
</asp:SqlDataSource>
I do hope it will save some time for others.
Stackoverflow is THE greatest and by far the best Q&A site on the web!!!
Gadi.
Here's my formview..
<asp:FormView ID="FormView1" runat="server" DataSourceID="SqlDataSource1" DataKeyNames="recid">
<EditItemTemplate>
RECID:
<asp:TextBox ID="recid" runat="server" Text='<%# Eval("RECID") %>' ReadOnly="true" />
<br />
SHIPPER:
<asp:TextBox ID="shipper" runat="server" Text='<%# Bind("SHIPPER") %>' />
<br />
<asp:LinkButton ID="UpdateButton" runat="server" CausesValidation="True" CommandName="Update" Text="Update" />
<asp:LinkButton ID="UpdateCancelButton" runat="server" CausesValidation="False" CommandName="Cancel" Text="Cancel" />
</EditItemTemplate>
</asp:FormView>
here's my sqldatasource1
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
ProviderName="<%$ ConnectionStrings:ConnectionString.ProviderName %>"
SelectCommand="SELECT * FROM IMPORT WHERE (RECID = ?)"
UpdateCommand="UPDATE IMPORT SET SHIPPER=#shipper WHERE RECID=#recid" >
<SelectParameters>
<asp:ControlParameter ControlID="Label1" Name="RECID" PropertyName="Text" Type="Int32" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="recid" Type="Int32" />
<asp:Parameter Name="shipper" Type="String" />
</UpdateParameters>
</asp:SqlDataSource>
Now, my problem is that everytime I update the page, this is the error Input string was not in a correct format.
I tried changing the #recid in the UpdateCommand into a constant UpdateCommand="UPDATE IMPORT SET SHIPPER=#shipper WHERE RECID=11186" this worked well, the update was successful.
I think the #recid is being treated as a string here in the UpdateCommand. Can someone please help me? What do I need to do in order to change the data type of #recid to Integer?
Thanks!
First thing you need to fix is to bind raceid with the textbox like below:
<asp:TextBox ID="recid" runat="server" Text='<%# Bind("RECID") %>' ReadOnly="true" />
Now there's a question about provider. In select command you have used RACEID = ?, ? is used for OleDb or Odbc. If you are using any of them, you have to change Update Command to this:
UpdateCommand="UPDATE IMPORT SET SHIPPER=? WHERE RECID=?"
And UpdateParameters to this (Notice their order):
<UpdateParameters>
<asp:Parameter Name="shipper" Type="String" />
<asp:Parameter Name="recid" Type="Int32" />
</UpdateParameters>
I would recommend reading this MSDN article: Using Parameters with the SqlDataSource Control
I have the following SqlDataSource
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:orangefreshConnectionString1 %>"
InsertCommand="INSERT INTO [Chat] ([Username], [Message]) VALUES (#Username, #Message)"
SelectCommand="SELECT [Id], [Username], [Message], [Date] FROM [Chat] ORDER BY [Id]" >
<InsertParameters>
<asp:Parameter Name="Message" Type="String" />
<asp:Parameter Name="Date" Type="DateTime" />
<asp:Parameter Name="Username" Type="String" />
</InsertParameters>
</asp:SqlDataSource>
Which controls the following FormView:
<asp:FormView ID="FormView1" runat="server" DefaultMode="Insert"
OnItemInserted="fv_ItemInserted" RenderOuterTable="False"
DataSourceID="SqlDataSource1">
<InsertItemTemplate>
<asp:Panel ID="Panel1" runat="server" DefaultButton="Button1">
<asp:TextBox ID="TextBox1" runat="server" CssClass="chattxtbox"
Text='<%# Bind("Message") %>' autocomplete="off"></asp:TextBox>
<asp:Button ID="Button1" runat="server" CommandName="insert" style="display:none" Text="Button" OnClick="insertUser"/>
</asp:Panel>
</InsertItemTemplate>
</asp:FormView>
I want to be able a variable's content into the Username column, so on Button1 I set the following event: OnClick="insertUser"
protected void insertUser(object sender, EventArgs e)
{
string username1 = User.Identity.Name;
SqlDataSource1.InsertParameters.Add("Username", username1);
SqlDataSource1.Insert();
}
This isn't working though, I don't get any SQL error message at all, is this the right way to do this? And where did I go wrong?
Change Insert Parameter to SessionParameter.
<InsertParameters>
<asp:Parameter Name="Message" Type="String" />
<asp:Parameter Name="Date" Type="DateTime" />
<asp:Parameter Name="Username" Type="String" />
<asp:SessionParameter Name="Username" SessionField="Username" Type="String" />
</InsertParameters>
And in Page_Load handler,
Session["Username"]=User.Identity.Name;
Here you want to declare your parameter as a Control Parameter and then you don't need to assign the value to the parameter in code. You can just call insert.
Solution at the bottom.
I receive the following error when trying to update records:
Must declare Scalar Variable #PaymentTermID
Problem is, #PaymentTermID should be defined already in the Update parameters. The 2 functions for onrowdatabound and onrowupdate are tweaked versions of the ones found here for the DropDownList: GridViewRow.DataItem Property. Delete works fine.
No new lines are added, just names changed around. Any help would be appreciated, I am not exactly used to working with asp objects.
<asp:GridView ID="GridView1" onrowdatabound="GridView1_RowDataBound" onrowupdating="GridView1_RowUpdating" runat="server" AutoGenerateColumns="False" DataKeyNames="PaymentTermID" DataSourceID="SqlDataSource1" CellPadding="1" CellSpacing="2">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:TemplateField HeaderText="Key Contract Date" SortExpression="Key Contract Date">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="SqlDataSource2" DataTextField="Key_Contract_Date" DataValueField="Key_Contract_Date" />
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:Production_DatabaseConnectionString %>"
SelectCommand="SELECT DISTINCT [Key Contract Date] AS Key_Contract_Date FROM [tblPRJ_PaymentTerms]" />
</EditItemTemplate>
<ItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("[Key Contract Date]") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Due Date" HeaderText="Due Date" SortExpression="Due Date" />
<asp:BoundField DataField="Percent Due" HeaderText="Percent Due" SortExpression="Percent Due" />
<asp:BoundField DataField="Custom Description" HeaderText="Custom Description" SortExpression="Custom Description" />
</Columns>
<HeaderStyle Font-Bold="True" ForeColor="#666666" />
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:Production_DatabaseConnectionString %>"
SelectCommand="SELECT * FROM [tblPRJ_PaymentTerms] WHERE ([Job Number] = #Job_Number)"
DeleteCommand="DELETE FROM [tblPRJ_PaymentTerms] WHERE [PaymentTermID] = #PaymentTermID"
InsertCommand="INSERT INTO [tblPRJ_PaymentTerms] ([Job Number], [Key Contract Date], [Due Date], [Percent Due], [Custom Description]) VALUES (#Job_Number, #Key_Contract_Date, #Due_Date, #Percent_Due, #Custom_Description)"
UpdateCommand="UPDATE [tblPRJ_PaymentTerms] SET [Job Number] = #Job_Number, [Key Contract Date] = #Key_Contract_Date, [Due Date] = #Due_Date, [Percent Due] = #Percent_Due, [Custom Description] = #Custom_Description WHERE [PaymentTermID] = #PaymentTermID">
<DeleteParameters>
<asp:Parameter Name="PaymentTermID" Type="Int32" />
</DeleteParameters>
<InsertParameters>
<asp:Parameter Name="Job_Number" Type="String" />
<asp:Parameter Name="Key_Contract_Date" Type="String" />
<asp:Parameter Name="Due_Date" Type="DateTime" />
<asp:Parameter Name="Percent_Due" Type="Decimal" />
<asp:Parameter Name="Custom_Description" Type="String" />
</InsertParameters>
<SelectParameters>
<asp:ControlParameter ControlID="txtCurrentJobNumber" Name="Job_Number" PropertyName="Text" Type="String" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="Job_Number" Type="String" />
<asp:Parameter Name="Key_Contract_Date" Type="String" />
<asp:Parameter Name="Due_Date" Type="DateTime" />
<asp:Parameter Name="Percent_Due" Type="Decimal" />
<asp:Parameter Name="Custom_Description" Type="String" />
<asp:Parameter Name="PaymentTermID" Type="Int32" />
</UpdateParameters>
</asp:SqlDataSource>
SOLUTION: There were multiple problems happening here. First and foremost, GuthMD was correct in his assessment of parameters needing a reference in terms of either a boundfield, templatefield, or other source (such as a control in the case of a control parameter). Simply creating an asp:boundfield for the PaymentTermID and setting the Visible property to false fixed the problem I posted about.
The other problem was that the database was setup poorly, and had spaces in column names. The OLEDB driver doesn't like that, and causes errors when you try to write back to the database and you have spaces in column names (even if it's encased in brackets []). After fixing the names in SQL, then revisiting our code and rewriting most of the SQL code for it, things started behaving as expected.
Thanks again for your help.
I've been looking through the MSDN documentation for Using Parameters, and it seems that for the binding to be created between the GridView and your SqlDataSource that your GridView is going to need to have BoundField elements corresponding to the Parameter elements.
Add the following to the <Columns> of your GridView:
<asp:BoundField DataField="Job_Number" Visible="false" />
<asp:BoundField DataField="Key_Contract_Date" Visible="false" />
<asp:BoundField DataField="Due_Date" Visible="false" />
<asp:BoundField DataField="Percent_Due" Visible="false" />
<asp:BoundField DataField="Custom_Description" Visible="false" />
<asp:BoundField DataField="PaymentTermID" Visible="false" />
1-The problem occurs when datasource is OleDb not SQLclient.
Change the DataSource1 to :
providerName="System.Data.SqlClient"
2-Make sure valid binding field in grid definition DataKeyNames="id_field"