First off, I'm still getting my web dev legs under me. I've combed through piles of SO posts, blogs, newsgroups and articles and I cannot seem to fix my problem. It's very similar to at least 10 different posts I've looked at.
I have an ASP gridview, which acts as a display and a select column. When you click select it throws the data into a detailsview. I have one field that needs to be a drop down box, but whenever I change the value and click update the value that is sent to the command is the original value.
Page Markup:
<asp:TemplateField HeaderText="Planner Name">
<ItemTemplate>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="cboCurrentPlanner" runat="server" DataSourceID="plannerDataSource"
DataTextField="planner_name" DataValueField="planner_id" SelectedValue='<%# Eval("planner_id") %>' AutoPostBack="true" ></asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="True" />
</Fields>
<FooterStyle BackColor="#CCCC99" ForeColor="Black" />
<HeaderStyle BackColor="#333333" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="White" ForeColor="Black" HorizontalAlign="Right" />
</asp:DetailsView>
sqlDataSource:
SelectCommand="SELECT vendor_key, vendor, planner_name, street, city, state_country, planner_id, country FROM V_MAP_MarkerInfo WHERE (vendor_key = #vendor_key)"
UpdateCommand="MAP_usp_webUpdatePlanToVendor"
UpdateCommandType="StoredProcedure" onupdating="mapDetailSource_Updating" >
<SelectParameters>
<asp:ControlParameter ControlID="GridView1" Name="vendor_key"
PropertyName="SelectedValue" Type="Int32" />
</SelectParameters>
<UpdateParameters>
<asp:Parameter Name="vendor_key" Type="String" />
<asp:Parameter Name="planner_id" Type="Int32" />
<asp:Parameter Name = "vendor" Type="String" />
</UpdateParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="plannerDataSource" runat="server"
ConnectionString="<%$ ConnectionStrings:vendor_mapConnectionString %>"
SelectCommand="SELECT [planner_id], [planner_name] FROM [MAP_planners]"
OldValuesParameterFormatString="original_{0}">
</asp:SqlDataSource>
I won't post the stored procedure code, I know that is working. The original value is the only value that makes it to the parameter.
I've tried all sorts of combinations of <%# Bind/Eval() %> postbacks but I can't find the right combination.
When I click select, I want the current planner to be selected in the dropdown list. When I select a new planner and click update I would like the planner to update. I'm not sure why this is so difficult or what I have royally screwed up to make it difficult but I am at my wits end. If at all possible, I would like an explanation of what is going on and not just the magical line of code that makes it work.
Flabbergasted is an understatement.
EDITS: ViewStateEnbabled="true" added to dropdownlist, the selectedIndexChanged event is firing.
EDIT AGAIN: Changed the planner_id to <asp:ControlParameter> added monitors to DetailsView1_OnDataBind and MapDataSource1_updating and the value is all over the place. but I can't see where it's being reset.
Do you have EnableViewState="false" set on the #Control or #Page settings? If viewstate is not enabled the control will always have the default value as the selected value. This can be set at the aspx level or the ascx level.
http://msdn.microsoft.com/en-us/library/ms972976.aspx
So I am a complete idiot, the DetailsView DataKeyNames property was not set correctly. I had accidentally added "planner_id" as a key from the wizard.
The code was fine all along. Thank you to everyone for trying, but I am a lost cause!
Related
I have a gridview populated with an sqldatasource. One of the columns of the gridview is a templatefield which contains a label as ItemTemplate, but in the EditItemTemplate I have a dropdownlist, instead of a textbox. I wanted to be able to edit a value from a certain column by selecting from a list of possible values.
So I created a second sqldatasource in order to extract the values from the database. I bounded the 2 sqldatasources. Visually it's ok. When I click on edit, the dropdownlist appears with the values that I want inside of it. When I select one of the values and click update, I get the error "
Input string was not in a correct format." I think I know why this is happening. Probably the values from the dropdownlist are type string and what I need is integer because that is the type for this column. I have tried setting the UpdateParameter as type Int32 but no luck. Is there any way to do this ?
This is the code I have used, but I have changed the column names with "Column_1", "Column_2", etc. In this example, "Column_6" is the templatefield with the dropdownlist in the edit.
<asp:GridView ID="DataUploadGridView" runat="server" AutoGenerateColumns="False" DataSourceID="First_DB" DataKeyNames="Column_3" >
<RowStyle HorizontalAlign="Center" />
<Columns>
<asp:BoundField DataField="Column_1" HeaderText="Column 1"/>
<asp:BoundField DataField="Column_2" HeaderText="Column 2"/>
<asp:BoundField DataField="Column_3" HeaderText="Column 3"/>
<asp:BoundField DataField="Column_4" HeaderText="Column 4"/>
<asp:BoundField DataField="Column_5" HeaderText="Column 5"/>
<asp:TemplateField HeaderText="Column 6">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList1" runat="server" DataSourceID="Second_DB" DataTextField="Column_6_Description" DataValueField="Column_6_ID"/>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("Column_6_ID") %>'/>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="true" HeaderText="Edit" />
<asp:CommandField ShowDeleteButton="true" HeaderText="Delete" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="First_DB" runat="server" ConnectionString="<%$ ConnectionStrings:MyConnectionString %>" OnSelecting="First_DB_Selecting" OnSelected="First_DB_Selected" OnInserted="First_DB_Inserted" OnInserting="First_DB_Inserting" OnDeleting="First_DB_Deleting" OnUpdating="First_DB_Updating"
SelectCommand ="SELECT * FROM [tblFirst_DB]
UpdateCommand ="UPDATE [tblFirst_DB]
SET [Column_1] = #Column_1,
[Column_2] = #Column_2,
[Column_3] = #Column_3,
[Column_4] = #Column_4,
[Column_5] = #Column_5,
[Column_6] = #Column_6
WHERE [Column_3] = #Column_3"
DeleteCommand ="DELETE FROM [tblFirst_DB] WHERE [Column_3] = #Column_3"
<UpdateParameters>
<asp:Parameter Name="Column_1" Type="String" />
<asp:Parameter Name="Column_2" Type="String" />
<asp:Parameter Name="Column_3" Type="String" />
<asp:Parameter Name="Column_4" Type="String" />
<asp:Parameter Name="Column_5" Type="Int32" />
<asp:Parameter Name="Column_6" Type="Int32" />
</UpdateParameters>
<DeleteParameters>
<asp:Parameter Name="Column_3" Type="String" />
</DeleteParameters>
</asp:SqlDataSource>
<asp:SqlDataSource ID="Second_DB" runat="server" ConnectionString="<%$ ConnectionStrings:MyConnectionString %>" SelectCommand="SELECT [Column_6_ID], [Column_6_Description] FROM [tblSecond_DB]"></asp:SqlDataSource>
Hopefully you are still here. So just to recap the problem. I'm getting an "
Input string was not in a correct format. " error because I need the Column_6 parameter to be integer and the values are coming from a dropdownlist which is probably making each value a string.
What can I do so that the value for Column_6 stays int upon updating it ?
The only thing that comes to mind right now is to pass the parameter from the code behind somehow. When I select the dropdownlist value, I should trigger an OnSelectedIndexChanged event. I'm thinking here is where I should cast the Selected_ID to an integer and somehow feed it into the first sqldatasource. But the value would go into a label so that will turn it into a string again. So no use...I'm really stuck on this. Any help is welcome.
Thank you !
Update: I've noticed that if I remove all the UpdateParameters, except the one from Column_6, I'm not getting the error anymore. However the value is not going in the gridview. It's an empty cell. I looked in the DB and it's null.
I think it's null because in the UpdateParameters I now have:
<UpdateParameters>
<asp:Parameter Name="Column_6" Type="Int32" />
</UpdateParameters>
It's not getting the value from anywhere. It should get it from the Second_DB sqldatasource. I tried changing it to:
<UpdateParameters>
<asp:ControlParameter Name="Column_6" ControlID="Second_DB" Type="Int32" />
</UpdateParameters>
But it's not really working out like I expected. I feel like I'm getting closer but no idea why it's behaving like this.
I have a WebForms GridView, where I want to update a BoundField conditionally (or I use a value from a DropDown or I use the text from a Textbox), based on the value from another DropDownList.
<asp:GridView ID="gv_results" runat="server" DataKeyNames="ID_RESULTS" DataSourceID="get_results">
<Columns>
<asp:TemplateField HeaderText="DETAIL" SortExpression="DETAIL">
<EditItemTemplate>
<asp:TextBox ID="tb_detail_edit" runat="server"></asp:TextBox>
<asp:DropDownList ID="dd_detail_edit" runat="server" AutoPostBack="True" DataSourceID="get_detail" DataTextField="DETAIL" DataValueField="DETAIL" ></asp:DropDownList>
</asp:SqlDataSource>
</EditItemTemplate>
<ItemTemplate>
<asp:SqlDataSource runat="server" ID="get_results"
UpdateCommand="UPDATE RESULTS SET [DETAIL] = COALESCE(#DETAIL,#DETAILwelcome)">
<UpdateParameters>
<asp:ControlParameter ControlID="ctl00$MainContent$gv_results$ctl02$dd_detail_edit" PropertyName="SelectedValue" Name="DETAIL" Type="String"></asp:ControlParameter>
<asp:ControlParameter ControlID="ctl00$MainContent$gv_results$ctl02$tb_detail_edit" PropertyName="Text" Name="DETAILwelcome" Type="String"></asp:ControlParameter>
</UpdateParameters>
</asp:SqlDataSource>
Well, I found out in the google's that I have to use the Direct ID in the Control Parameter. And it works...the thing is , the $ctl02 (for example) before the id of the dd_detail_edit, changes, with different rows in the Gridview (so this id works for one row, but maybe for the next it doesn't work.
Is there some workaround for this?
Using only something like $gv_results$dd_detail_edit , doesn't work, I dunno why :S
TIA and Best Regards,
For one thing it looks like you have an open <ItemTemplate> tag without any closing one.
If you check out the .net documentation you can see where they use the regular control IDs, like ControlID = dd_detail_edit.
I do not think you're providing enough details for me to provide a complete answer, but those are a couple of things I noticed.
I have just started to learn how to use the Gridview Control to display SQL data. I have been able to get almost everything to work except for displaying the more user friendly information for one of my data fields that I populate from a lookup table. The entire concept of the page I want to be able to Update, Insert and Delete new records too and for some reason I could not get these options to work when I was using the SqlDataSource so I use LinqDataSource and all is now working (except I haven’t figured out Insert yet…a separate question)
I am also using the controls tabs in Visual Studio to choose and edit the attributes of the controls so kind of using the wizards and not hand coding the example.
What I cannot figure out is how to make my column with employeetypeid that contains the foreign key from the employeetypelookup table to show the employeetype text value for the user so this makes more sense. I found a “Walkthrough: Displaying a Drop-Down List While Editing in the GridView Web Server Control“ and this works perfectly. When I go into edit mode the dropdownlist shows the employeetype text and when I choose a different type, the appropriate employeetype id gets stored in the database.
So how can I modify something (the Datasource???) to display the employeetype text in the DataGrid.
<asp:LinqDataSource ID="LinqDataSource1" runat="server" ContextTypeName="SNRmain.SNRmainDataContext" EntityTypeName="" OrderBy="lastname, preferredfirstname" Select="new (personnelid, lastfirstname)" TableName="masterpersonnellastpreferreds"></asp:LinqDataSource>
<asp:DropDownList ID="DropDownList1" runat="server" AutoPostBack="True" DataSourceID="LinqDataSource1" DataTextField="lastfirstname" DataValueField="personnelid">
</asp:DropDownList>
<asp:LinqDataSource ID="LinqDataSource2" runat="server" ContextTypeName="SNRmain.SNRmainDataContext" EnableDelete="True" EnableInsert="True" EnableUpdate="True" EntityTypeName="" TableName="tblappointmentdates" Where="personnelid == #personnelid" OrderBy="startdate desc">
<WhereParameters>
<asp:ControlParameter ControlID="DropDownList1" Name="personnelid" PropertyName="SelectedValue" Type="Int32" />
</WhereParameters>
</asp:LinqDataSource>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="snrappointmentid" DataSourceID="LinqDataSource2">
<Columns>
<asp:CommandField ShowDeleteButton="True" ShowEditButton="True" />
<asp:BoundField DataField="startdate" HeaderText="startdate" SortExpression="startdate" />
<asp:BoundField DataField="endingdate" HeaderText="endingdate" SortExpression="endingdate" />
<asp:TemplateField HeaderText="employeetypeid" SortExpression="employeetypeid">
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server" DataSourceID="LinqDataSource3" DataTextField="employeetypetext" DataValueField="employeetypeid" SelectedValue='<%# Bind("employeetypeid", "{0}") %>'>
</asp:DropDownList>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("employeetypeid") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="apptcomment" HeaderText="apptcomment" SortExpression="apptcomment" />
<asp:BoundField DataField="dateentered" HeaderText="dateentered" SortExpression="dateentered" />
</Columns>
</asp:GridView>
<asp:LinqDataSource ID="LinqDataSource3" runat="server" ContextTypeName="SNRmain.SNRmainDataContext" EntityTypeName="" OrderBy="employeetypetext" Select="new (employeetypeid, employeetypetext)" TableName="tblemployeetypelookups">
</asp:LinqDataSource>
I have tried to modify the LinqDataSource2 to include a statement like the one below but that does not work and I get an error that does not make sense to me. "System.Web.Query.Dynameic.ParseException: Syntax error.
<asp:LinqDataSource ID="LinqDataSource2" runat="server" ContextTypeName="SNRmain.SNRmainDataContext" EntityTypeName="" Select="snrappointmentid,
personnelid, startdate,
endingdate, employeetypeid,
tblemployeetypelookup.employeetypetext
from tblappointmentdates
join tblemployeetypelookups on tblappointmentdates.employeetypeid = tblemployeetypelookups.employeetypeid" TableName="tblappointmentdates" Where="personnelid == #personnelid">
<WhereParameters>
<asp:ControlParameter ControlID="DropDownList1" Name="personnelid" PropertyName="SelectedValue" Type="Int32" />
</WhereParameters>
</asp:LinqDataSource>
thanks in advance.
Ok if I understood correctly what you should do is to pass the employeetypeid in a function and retrieve the text and bind that to control like this.
from
<asp:Label ID="Label1" runat="server" Text='<%# Bind("employeetypeid") %>'></asp:Label>
to
<asp:Label ID="Label1" runat="server" Text='<% #GetEmployeeName(Eval("employeetypeid"))%>' runat="server" />
so now GetEmployeeName is a server function you would write to fetch name from id.
protected string GetEmployeeName(int employeetypeid)
{
//What ever is the way to query and return from here
}
Also as side note I noticed you do naming like Label1 which is very poor practice.
I'm still a newbie in ASP.NET, and right now, my Gridview is not "updating" when I hit "Update". Here is how I have my GridView w/ the SqlDataSource :
<asp:GridView ID="ProjectTable" runat="server" AutoGenerateColumns="False" AutoGenerateEditButton="True" DataSourceID="PopulateProjectTable" DataKeyNames="ProjectID">
<Columns>
<asp:BoundField DataField="ProjectID" HeaderText="Project ID" ReadOnly="True" SortExpression="ProjectID" />
<asp:BoundField DataField="ProjectDescription" HeaderText="Project Description" ReadOnly="True" SortExpression="ProjectDescription" />
<asp:BoundField DataField="ProjectNotes" HeaderText="Project Notes" SortExpression="ProjectNotes" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="PopulateProjectTable" runat="server" ConnectionString="<%$ ConnectionStrings:sandboxConnectionString %>" SelectCommand="SELECT * FROM [Projects]" UpdateCommand="UPDATE [Projects] SET ProjectNotes = #project_notes">
<UpdateParameters>
<asp:Parameter Name="project_notes" Type="String" />
</UpdateParameters>
</asp:SqlDataSource>
I have no code in the code behind. When I hit "Edit", the third column is suppose to be "editable". When I hit "Update", the page does a postback but what was entered in the third column does not persist and is instead lost. What is going on?
In addition, how would I trace this issue? This is so in the future, I can see what the SQL string is. Thank you.
EDIT: Turns out to be a typo that caused my issue. Problem solved!
Is the spelling correct on the ProjectNotes DataField? The problem you are describing sounds like the field is not bound properly.
I would run SQL profiler while hitting the update. To see what exactly was being sent back to the Database.
You should see your parameter as well. Set the filter to the DB your looking at if you have multiple and give it a try and realtime run the same test by hitting the update button again.
Please modify your update command from this
UpdateCommand="UPDATE [Projects] SET ProjectNotes = #project_notes"
to this
UpdateCommand="UPDATE [Projects] SET ProjectNotes = #project_notes" WHERE ProjectID=#ProjectID
Please add to your DataSource
OnUpdated="OnDSUpdatedHandler">
and add the following method
<script runat="server">
private void OnDSUpdatedHandler(Object source, SqlDataSourceStatusEventArgs e) {
var dbg = e;
}
</script>
Set breakpoint on line
var dbg = e;
and examine what is being in that variable. The answer should be there
I'm trying to allow for editing of the items in a GridView (the DataSource is a database connection). Every example I find has complicated examples implemented within. I'd like to know what the simplest change(s) I need to do are in order to allow for editing of items in the GridView.
In other words, how can I modify the following to allow for editing?
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataSourceID="SqlDataSourceWS">
<Columns>
<asp:CommandField ShowSelectButton="True" />
<asp:BoundField DataField="id" HeaderText="id" InsertVisible="False" ReadOnly="True" SortExpression="id" />
<asp:BoundField DataField="NAME" HeaderText="NAME" SortExpression="NAME" />
<asp:BoundField DataField="ACCESS_TO" HeaderText="ACCESS_TO" SortExpression="ACCESS_TO" />
</Columns>
</asp:GridView>
Obviously I'd need to add code as well, but I'm just not sure how to start with this.
EDIT: I thought I'd specified, but I didn't - it's an SQLDataSource.
There are several thing you need to do to enable editing
Assuming that your data source is an SQLDataSource
1) Add a command field to your girdview columns
<asp:CommandField ButtonType="Button" EditText="Edit" ShowEditButton="true"/>
2) Add an update command to your data source
<asp:SqlDataSource ID="SqlDataSourceWS" runat="server"
ConnectionString="<%$ Connection String %>"
SelectCommand=" SELECT COMMAND HERE "
UpdateCommand=" UPDATE COMMAND HERE ">
<UpdateParameters>
<asp:Parameter Name="" />
<asp:Parameter Name="" />
</UpdateParameters>
</asp:SqlDataSource>
For more information on the command field and how to use it you can look at the Microsoft Developer Network Documentation
EDIT
Here is a very simple example of a SQLDatasource that shows how you may update an item
<asp:SqlDataSource ID="sqlMeetings" runat="server"
ConnectionString="<%$ connection %>"
SelectCommand="SELECT [meetingid]
,[groupname]
,[meetingtime]
,[meetingdate]
FROM [DCMS].[dbo].[tbl_meetings] "
UpdateCommand="UPDATE tbl_meetings
SET meetingdate = #meetingdate, meetingtime = #meetingtime
WHERE meetingid = #meetingid">
<UpdateParameters>
<asp:Parameter Name="meetingdate" />
<asp:Parameter Name="meetingtime" />
</UpdateParameters>
</asp:SqlDataSource>
From the example above you can see that I am selecting 3 fields from the data base but only allowing for two to be updated (meetingdate and meetingtime).
To edit the records, the GridView must enter EditMode. The grid changes modes according to the commands it receives, in this case "edit". See the remarks on the gridview page, 'Data Operations' section, for more info.
There are basically three ways to fire the command and enter edit mode on the grid:
Use the AutoGenerateEditButton property on the grid
Use a CommandField with ShowEditButton like the other answer stated
Use a custom TemplateField with a LinkButton inside like this:
<Columns>
...
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton runat="server" Text="Edit" CommandName="Edit" />
</ItemTemplate>
<EditItemTemplate>
<asp:LinkButton runat="server" Text="Update" CommandName="Update" />
<asp:LinkButton runat="server" Text="Cancel" CommandName="Cancel" />
</EditItemTemplate>
</asp:TemplateField>
...
</Columns>
After that, it will depend on which DataSource control you are using. With an EntityDataSource, for instance, all you need to do is set EnableUpdate="true"