How to pass value using ImageButton to update database? - asp.net

I having problem when I try to pass value from ImageButton to a controlparameter, then the update command can retrieve the value from control parameter to execute update statement.
I want to pass value Status=1 when ImageButton APPROVE is clicked, else pass value Status=2 when ImageButton REJECT is clicked.
Where and how should I assign value Status?
When I run my code, I receive this error : Must declare the scalar variable "#Status".
Or any recommendation to pass the value Status?
My ImageButton:
<ItemTemplate>
<asp:ImageButton runat="server" ID="APPROVE" CommandName="update"
ImageUrl="~/images/accept.png"
OnClientClick="if (!window.confirm('Are you sure you want to approve this booking?')) return false;" />
</ItemTemplate>
<ItemTemplate>
<asp:ImageButton runat="server" ID="REJECT" CommandName="update"
ImageUrl="~/images/reject.png"
OnClientClick="if (!window.confirm('Are you sure you want to reject this booking?')) return false;" />
</ItemTemplate>
My UPDATE statement
UpdateCommand="UPDATE [bookingschedule] SET status=#Status WHERE [bookingScheduleID] = #bookingScheduleID"
My ControlParameter
<UpdateParameters>
<asp:Parameter Name="bookingScheduleID" Type="Int32" />
<asp:ControlParameter Name="Status" ControlID="APPROVE" Type="Int32" />
<asp:ControlParameter Name="Status" ControlID="REJECT" Type="Int32" />
</UpdateParameters>

A button does not have a value in html and thus you can't use it in the ControlParameter declaration. One solution is to make a hidden textbox on the form. Lets call it "StatusType".
<input type="hidden" name="StatusType" value="0">
Now, in the "OnClientClick" of each of the buttons; assign the StatusType's value to either 1 or 2 (or whatever your defined status codes are).
OnClientClick="if (!window.confirm('Are you sure you want to reject this booking?')) {
return;
}
else {
$('#StatusType').val(0);
}"
Then use "StatusType" in the ControlParameter.
<asp:ControlParameter Name="Status" ControlID="StatusType" Type="Int32" />

Have you tried using the CommandArgument property of the ImageButton?
From MSDN:
Sometimes, multiple ImageButton controls are related and share the same value for the CommandName property, such as Sort. Use this property to supplement the CommandName property with additional information about the command to perform, such as Ascending. The values of the CommandName and CommandArgument properties are typically used in the OnCommand event handler to determine the action to perform when the ImageButton control is clicked.
<asp:ImageButton id="imagebutton1" runat="server"
AlternateText="Sort Ascending"
ImageUrl="images/pict.jpg"
OnCommand="ImageButton_Command"
CommandName="Sort"
CommandArgument="Ascending"/>

Related

Select Method with ControlParameter defaultvalue property behavior

I'm using an objectdatasource with my gridview, the ODS's SelectMethod is working but not the way I want, I'm sure it's something to do with the DefaultValue property but I've already tried to set it with no luck.
here's the code:
<asp:ObjectDataSource ID="AppointmentsDataSource" runat="server"
TypeName="DAL"
DataObjectTypeName="DatabaseModel.Appointment"
SelectMethod="getAppointmentsfiltered">
<SelectParameters>
<asp:ControlParameter ControlID="txtCal" PropertyName="Text" Type="DateTime" Name="chosenDate" DefaultValue="" />
</SelectParameters>
</asp:ObjectDataSource>
Public Function getAppointmentsfiltered(chosenDate As DateTime) As IEnumerable(Of Appointment)
If String.IsNullOrEmpty(chosenDate) Then
Return GetAllAppointments()
Else
Dim appts = (From a In context.Appointments.Include("Client")
Where a.AppointmentDate.Equals(chosenDate)
Select a).ToList()
Return appts
End If
End Function
Public Function GetAllAppointments() As IEnumerable(Of DatabaseModel.Appointment)
Dim AllAppointments = (From a In context.Appointments.Include("Client")
Order By a.AppointmentDate Descending
Select a).ToList()
Return AllAppointments
End Function
my textbox:
<asp:TextBox ID="txtCal" runat="server" AutoPostBack="true" OnTextChanged="txtCal_TextChanged" Text=""></asp:TextBox>
<img id="caltrigger" alt="Click this icon to display the calendar" src="../Images/calendar-icon.png" width="18" height="20" />
<asp:CalendarExtender ID="CalendarExtender1" runat="server" TargetControlID="txtCal" PopupButtonID="caltrigger">
</asp:CalendarExtender>
As you can see, I want to see all the appointments in the gridview initially since the value of my date textbox is empty. The filtering works fine.
Any help would be appreciated, and forgive my ignorance but I'm fairly new to asp.net
EDIT: I ended up declaring two ODS in markup and switching at runtime, which takes care of this issue but if anybody can tell me why the above code didn't work i'd appreciate it.

Using a dropdownlist control inside a formview

I am new to asp.net and i have a problem using a dropdownlist control inside a formview and passing its value to the related sqldatasource. When i use the code below i get the following exception
Exception Details: System.InvalidOperationException: Could not find control 'ddlCategory' in ControlParameter 'categoryId'.
The Dropdownlist inside a formview.
<asp:DropDownList ID="ddlCategory" DataSourceID="ObjectDataSourceCategory" DataTextField="NAME" DataValueField="ID" runat="server" />
The SQL Data Source
<asp:ObjectDataSource ID="sqlDataSourceItem" TypeName="Item" runat="server"
SelectMethod="getItem"
InsertMethod="insertItem"
UpdateMethod="updateItem">
<SelectParameters>
<asp:QueryStringParameter QueryStringField="id" Name="id" />
</SelectParameters>
<InsertParameters>
<asp:ControlParameter ControlID="ddlCategory" Name="categoryId" PropertyName="selectedValue" />
</InsertParameters>
</asp:ObjectDataSource>
And i have found the solution to this problem. I have changed the ID of the DDL in the control parameter. It works like below since this is the final generated id of that control. But i think there must be an easier and better way. Any help would be appriciated.
<asp:ControlParameter ControlID="ctl00$main$frmViewItem$ddlCategory" Name="categoryId" PropertyName="selectedValue" />
This answer will provide a solution to your problem:
You need a recursive findcontrol() method.
It is because of your ddlCategory is inside formview and you are using the master page. The best way is to overwrite the 'FindControl' function of master page.
pls see the following link for detail:
http://geekswithblogs.net/AzamSharp/archive/2006/08/27/89475.aspx

Why my combobox count is 0?

Why the count of items in my ComboBox is always 0 although the datasource of this combobox has data !!
<div align="right" dir="rtl">
<asp:Label ID="lbl_contactListName" runat="server" Text="Menu Name :" CssClass="span"></asp:Label>
<telerik:RadComboBox ID="ddl_contactList" runat="server" AutoPostBack="True" CausesValidation="False"
CollapseDelay="0" Culture="ar-EG" ExpandDelay="0" Filter="StartsWith" ItemsPerRequest="10"
MarkFirstMatch="true" Skin="Outlook" EnableAutomaticLoadOnDemand="True" EmptyMessage="-New Menu-"
ShowMoreResultsBox="True" OnSelectedIndexChanged="ddl_contactList_SelectedIndexChanged"
EnableVirtualScrolling="True" DataTextField="list_desc" DataValueField="list_code"
DataSourceID="ObjectDataSource1" EnableViewState="true" Width="300px">
</telerik:RadComboBox>
</div>
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server" SelectMethod="GetContactListsByDep"
TypeName="SendSMS_EmailModule.ContactList">
<SelectParameters>
<asp:SessionParameter Name="year" SessionField="year" Type="Int32" />
<asp:SessionParameter Name="main_code" SessionField="main_code" Type="Int32" />
</SelectParameters>
</asp:ObjectDataSource>
The property value of of Rad combo "EnableAutomaticLoadOnDemand=True" here.This property load all the data on demand. So when you click on your combobox it will load the data in it untill that it is empty. If you do not want to make your combo on demand then Make that property false. By doing that you will get the count directly.
If you want to keep that EnableAutomaticLoadOnDemand property to True. you can use ItemDataBound event of the Rad Combo. By using it you can change the Item's Text and Value properties as well as modify its Attributes collection based on the DataItem
You will find more details at telerik rad combo. Let me know if you want more detail on this.
Perhaps you should call DataBind() before you call Count().
ddl_contactList.DataBind();
ddl_contactList.Items.Count();
Are you getting the Count as Zero on Page Load.
If that's the case it is because the page load event hits before the ComboBox is populated. An easier way is to populate the items on Page Load itself.
(This code is untested)
if(!Page.IsPostBack)
{
using(var context = new Entities())
{
foreach(var item in context.Employee)
{
RadComboBox1.Items.Add(new RadListBoxItem(item.Name, item.ID.ToString()));
}
}
}
//Here you can get the count.

GridView and DropDownlist

I have a gridview that when enter to edit mode one of the column change to dropdownlist:
<EditItemTemplate>
<asp:DropDownList ID="DropDownList2" runat="server"
DataSourceID="SqlDataSource1" DataTextField="name" DataValueField="name">
</asp:DropDownList>
</EditItemTemplate>
Now i have a SqlDataSource with update method that define in this aspx file:
<UpdateParameters>
<asp:Parameter Name="name" Type="String" />
<asp:ControlParameter ControlID="DropDownList2" Type="string"
PropertyName="SelectedValue" Name="genre" />
</UpdateParameters>
now i want to get the selected value and insert it but when i press the Update button in the row in the gridview i get this error:
Could not find control 'DropDownList2' in ControlParameter 'genre'
any idea why it happen?
Yes. ControlParameters only work when the DOM can find the control you're referring to that's within the same branch of the GridView. The problem is that Gridviews are a poor way of handling DOM controls because as soon as you go into a "mode" of the GridView like the EDIT mode, the entire DOM structure changes. The DOM by the way, is the Document Object Model. Because it's changed, therefore ASP cannot find the control you're referring to.
I've overcome this by doing one of two things.
First see if it works by simply tailing the control name with the '$' character.
<UpdateParameters>
<asp:Parameter Name="name" Type="String" />
<asp:ControlParameter ControlID="MyGridView$DropDownList2" Type="string"
PropertyName="SelectedValue" Name="genre" />
</UpdateParameters>
This sometimes works if you're lucky.
If not, then you'll need to find the control, get its value and pass it into the SQL parameter programmatically in code behind.
Try something like this (I use C#) ...
protected void MyGridView_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
...
GridViewRow gvRow = (GridViewRow)sender;
DropDownList myDDL = (DropDownList)gvRow.FindControl("DropDownList2");
if (myDDL != null)
{
//assuming your datasource is outside the gridview, you have to find it!
SqlDataSource sds1 = (SqlDataSource)page.FindControl("myDataSource");
if (sds1 != null)
{
sds1.UpdateParameter["genre"].DefaultValue = myDDL.SelectedValue;
... and do your databinding etc
sds1.Update();
}
}
}
I always rely on the client-side code (ASPX) to do most of the work for me, like Bind(), Eval(), etc, but over time you'll realise that to really control your program, you'll have to rely on JavaScript or code behind to do the finer bits. ASP is not always "clever" in doing what you expect it to do.

EntityDataSource Null Update Pameters not getting marked Modified

I am using an EntityDataSource with a FormView on VB.NET application. The FormView contains an AjaxControlToolKit TabContains with multiple tabs. Due to the fact that each tab is a naming container, Bind doesn't work properly for updating values (as discovered from reading other posts on stackoverflow). I instead have to declare UpdateParameters on my EntityDataSource. Example markup is as follows:
<asp:FormView ID="fv" runat="server" DataSourceID="eds" DataKeyNames="ID">
<EditItemTemplate>
<asp:TabContainer ID="tc" runat="server">
<asp:TabPanel ID="tp" runat="server" HeaderText="Tab 1">
<ContentTemplate>
<asp:TextBox ID="tbName" runat="server" Text='<%#Eval("Name") %>'></asp:TextBox>
</ContentTemplate>
</asp:TabPanel>
</asp:TabContainer>
</EditItemTemplate>
</asp:FormView>
<asp:EntityDataSource ID="eds" runat="server" ConnectionString="name=NDSEntities"
DefaultContainerName="NDSEntities" EnableFlattening="False" EntitySetName="Customers"
Where="it.ID = #ID" EnableUpdate="true" EnableInsert="true">
<WhereParameters>
<asp:QueryStringParameter Name="ID" QueryStringField="ID" DbType="Guid" />
</WhereParameters>
<UpdateParameters>
<asp:ControlParameter Name="Name" ControlID="fv$tc$tp$tbName" DbType="String" />
</UpdateParameters>
<InsertParameters>
<asp:ControlParameter Name="Name" ControlID="fv$tc$tp$tbName" DbType="String" />
</InsertParameters>
</EntityDataSource>
This works great, until a customer is edited and their name is set to nothing (assuming in this case, a null name is allowed). The Name UpdateParameter is set to Null but the ObjectStateEntry is not set to modified for Null properties, even if previously the Entity had a value specified. As long as the name is changed to something other than Null, everything is updated correctly.
I found a workaround by putting the following code in the Updating event of the EntityDataSource.
Dim ose As ObjectStateEntry = context.ObjectStateManager.GetObjectStateEntry(action)
For Each p As Parameter In eds.UpdateParameters
ose.SetModifiedProperty(p.Name)
Next
This makes sure that each property in the UpdateParameters has its state set to modified. It works, but it seems like a hack and I can see it causing problems down the road. Is there anything else I could do?
Do you have an "Concurrency Mode" set for the entity in question? Depending on how you actually update the entity (I haven't used the EntityDataSource, but I'm guessing it internally uses the ObjectContext.Attach method), the code that creates the SQL statement, will try to update only those columns that are actually changed.
Consider the following:
void UpdatePersonEntity(int id, string firstName, string lastName)
{
Person p = new Person { Id = id };
this.Context.People.Attach(p);
p.FirstName = firstName;
p.LastName = lastName;
this.Context.SaveChanges();
}
If firstName or lastName is null, the ObjectContext would assume that it's original value hasn't been touched. This might be something you should look into. I apologize if this isn't helpful, but it might push you in the right direction.

Resources