validate a template text box with database value - asp.net

I'm developing a website and have a textbox in gridview template field. This textbox collects the input for the "order quantity" which has to be compared against the "available quantity"(stored in the database).
I use RowEditing, RowUpdating and RowCanceling events for edit operations in gridview.
I tried implementing the above requirement with "TextChanged" Event of text box. But the issue is, when the user edits the quantity and clicks on "Update" button, text box event fires first and update button event doesn't fire. So, user is forced to click the "Update" button again.
Is there any work around for the above scenario or any other event used to implement above requirement?
Thanks,
Balaji g

You can Use RangeValidator For That...
<asp:RangeValidator ID="RangeValidator1" ControlToValidate="YourTexBoxId"
runat="server" MinimumValue="0" Type="Integer"
MaximumValue='<%# GetQuantity(Eval(TotalQaunt).ToString(),Eval(ItemId).ToString()) %>'
ErrorMessage="RangeValidator"></asp:RangeValidator>
write a function lyk this ON CODE BEHIND
string GetQuantity(string totalquantity,string itemid)
{
DO OPERATRION TO GET QUANTITY.....
return quantity;
}

I think I'd try the CustomValidator. With the CustomValidator, you can define the validation code in the "_ServerValidate" event handler.
In your validation code, you can call the database to get the current value and then compare it to the submitted value (which would be available via the event handler's ServerValidateEventArgs paramenter if you specify a ControlToValidate).
In order to look up the current value in the database, you'll need to know which record was clicked. For that, you could either use the row button's CommandArgument property or include a hidden field in your row to store some type of ID. Then you could capture that ID and use it to look up the desired record in the database.
Updated with Code
Protected Sub cusCustom_ServerValidate(source As Object, args As System.Web.UI.WebControls.ServerValidateEventArgs)
Dim cv As CustomValidator = CType(source, CustomValidator)
Dim HiddenField_ID As HiddenField = CType(cv.Parent.FindControl("HiddenField_ID"), HiddenField)
*** Use ID to look up value in database ***
End Sub

Related

Calling Code Behind Function and passing arguments

I have asp.net text box where I am calling the code behind function through __postback but I also want to pass text of the text box which is calling __postback function.
Here is my text box.
<asp:TextBox Width="400px" ID="txtExtraRooms" MaxLength="3"
onkeypress="__doPostBack(this.name,'OnKeyPress');" runat="server"
Visible="false"></asp:TextBox>
And my code behind where I want to get entered text of text box with id="txtExtraRooms"
Dim ctrlName As String = Request.Params(Page.postEventSourceID)
Dim args As String = Request.Params(Page.postEventArgumentID)
// here I want text of text box with id "txtExtraRooms"
If ((ctrlName = txtExtraRooms.UniqueID) _
AndAlso (args = "OnKeyPress")) Then
TextBox2_OnKeyPress(ctrlName, args)
End If
The delegate for any asp.net event has the 1st argument as the "sender" which holds the reference to the control raising the event.
For textbox, you should use the TextChanged event rather than doing the postback (which will require state management as well).
Add an AutoPostback=true on textbox and provide the TextChanged=handler. The page postback will happen, although handling will be on the provided handler.
Also, by using the "keypress" event it will fire for each key typed (entered or deleted). Rather the event should fire when user has completed providing the input and has moved the focus to another control.
In asp.net there are 2 main fields that you can check in the form object which are
__EVENTTARGET: The Control Which raised the event for postback
__EVENTARGUMENT: Arguments Passed
and to read them you can use :
Dim eventArgument As String = IIf(Me.Request("__EVENTARGUMENT") = Nothing,
String.Empty, Me.Request("__EVENTARGUMENT"))
for more details you can check
https://forums.asp.net/t/1252181.aspx?Retreiving+Argument+from+_doPostBack+in+VB

Display query string in asp.net controls

I'm writing an ASP web application with VB back-end. What I'd like to do is generate a url and display this in control on the page. For example if I have a label and a button on the form. The label is blank. When the button is clicked the following code fires:
Protected Sub btnGenerate_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnGenerate.Click
label1.Text = "Hello"
End Sub
What I'd like to have is a url that would point to my ASP Page with the words "Hello" in the label. Is this possible?
You could do the following:
{siteaddress}/aspxpage.aspx?label=hello
then in you aspx page do something like:
<asp:label runat="server" id="yourLabelId" text='<%=Request.QueryString("label")%>' />
Or in the Page_Load:
yourLabelId.Text = Request.QueryString("label")
I would recommend validating the data before just writing it into the page.
Pass the text in query string e.g. suppose relative path of the page is /pagename.aspx , you can pass the query string as per given example below:
/pagename.aspx?text=hello
in c# write following code in Page_Load event
//You don't have to check the url all the time , so just check it if page is not posting back (first time after user visits the page and ignore all other same page post backs. Label can maintain its control state (text value) after every postback, so assign it only once to increase performance
if (!IsPostBack)
{
//Check if query string is provided or not , if it is not provided take some default text, I am taking empty string as default text.
string givenText = (Request.QueryString["text"] == null)?"":Request.QueryString["text"];
label1.Text = givenText;
}
You can also create a property for text given through query string and default text.

Replace detailview field before insert

Is there a way to edit an hidden field value of detailsview before inserting? I want to replace it with another value. Which event can I use?
You can use ItemInserting event.
It can be done on the ItemInserting event of the DetailsView control. Here's how:
Private Sub DetailsView1_ItemInserting(sender As Object, e As System.Web.UI.WebControls.DetailsViewInsertEventArgs) Handles DetailsView1.ItemInserting
e.Values("ProductName") = "Your New Value"
End Sub
Basically e.Values is a collection of ordered KetValuePairs which contain your DetailsView insert form entries. You can reference them by index or by key. In the example above I reference them by key - "ProductName" in my case since I used the Products table of the Northwind database. Hope this helps...

Why is My GridView FooterRow Referencing the Wrong Row?

I have a GridView and, using a fairly common method, I'm using a FooterRow and TemplateFields to provide the missing insert ability. So far so good.
The footer contains a TemplateField with a LinkButton to provide the postback that does the insertion. In the handler for the LinkButton's click, the Insert() method is called on the ObjectDataSource that the GridView is bound to. The ObjectDataSource's insert parameters are populated in the handler for its Inserting event. The code for all of this (abridged) looks like this:
Markup:
<asp:GridView ID="gvComplexRates" runat="server" AutoGenerateColumns="False"
DataKeyNames="id" DataSourceID="odsComplexMileageRates"
EnableModelValidation="True" ShowFooter="True">
<Columns>
<asp:TemplateField ShowHeader="False">
:
:
<FooterTemplate>
<asp:LinkButton ID="addLinkButton" runat="server" CausesValidation="false"
CommandName="Insert" Text="Add"></asp:LinkButton>
</FooterTemplate>
</asp:TemplateField>
:
:
</asp:GridView>
Code Behind:
Private Sub gvComplexRates_RowCommand(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewCommandEventArgs) Handles gvComplexRates.RowCommand
Select Case e.CommandName
Case "Insert"
odsComplexMileageRates.Insert()
End Select
End Sub
Private Sub odsComplexMileageRates_Inserting(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ObjectDataSourceMethodEventArgs) Handles odsComplexMileageRates.Inserting
Dim fuelTypeDropDown As DropDownList = gvComplexRates.FooterRow.FindControl("ddFuelTypeInsert")
Dim engineTypeDropDown As DropDownList = gvComplexRates.FooterRow.FindControl("ddEngineTypeInsert")
Dim rateTextBox As TextBox = gvComplexRates.FooterRow.FindControl("tbRateInsert")
Dim vatRateTextBox As TextBox = gvComplexRates.FooterRow.FindControl("tbVatRateInsert")
e.InputParameters("expense_type_id") = ddExpenseTypeSelect.SelectedValue
e.InputParameters("fuel_type_id") = fuelTypeDropDown.SelectedValue
e.InputParameters("engine_type_id") = engineTypeDropDown.SelectedValue
e.InputParameters("rate") = rateTextBox.Text
e.InputParameters("vat_rate") = vatRateTextBox.Text
End Sub
Two of the fields in my FooterRow are DropDownLists that are populated from other tables. Again this works fine and I can add, edit and remove rows without problem.
The problem comes when I use a modal dialog from this page to insert extra rows into the tables used to populate the DropDownLists in the FooterRow. The insert operations work fine and the modal dialog closes and at this point I use a javascript postback (basically a call to __doPostBack()) so that my FooterRow DropDownLists can be updated. The code for this is:
Protected Sub updateFuelEngineDropdowns()
odsFuelTypes.Select()
odsEngineTypes.Select()
Dim dropDown As DropDownList = gvComplexRates.FooterRow.FindControl("ddFuelTypeInsert")
dropDown.DataBind()
dropDown = gvComplexRates.FooterRow.FindControl("ddEngineTypeInsert")
dropDown.DataBind()
End Sub
This sub, updateFuelEngineDropdowns(), is called from the Page Load event. The first time I called it it worked fine. For some reason in subsequent runs through the debugger I'm getting NullReferenceExceptions. Digging into the debug object viewer it is apparent that the GridView FooterRow is referencing the row above the footer which contains no controls (at least not at this non-editing stage) and so, quite reasonably, gives my the Null reference.
The debug QuickView expressions I use are:
gvComplexRates.FooterRow.Controls(3)
DirectCast(gvComplexRates.FooterRow.Controls(3),System.Web.UI.WebControls.DataControlFieldCell).Controls(1)
The first of these shows a tag of td. Which makes sense. The second shows text of "10" which is the content for the row above the footer.
Does anybody know why this is happening?
Thanks Dan
Where are you "providing the missing insert ability"?
You have to rebuild the footer-controls on every postback, the GridView.RowCreated-Event would be a good place.
Update:
You have to Databind your GridView after you inserted new rows into your Dropdowns' Tables.
Right, this is a bit embarrassing. I gave a little white lie in the original question. By omission rather than a deliberate attempt to mislead. I am not, in fact, using a GridView but a subclass of it that will display rows when the datasource contains no data. This enables the user to insert new rows when the table is empty. This subclass overrides the FooterRow property and, to my shame, it was this that was getting things wrong. So I made two errors here: first I failed to test my GridView subclass properly and second I sought to prevent what I thought would be unnecessary attention on my subclass by not showing its use in the code snippets I included in the question. My bad. Thanks to Tim for taking the time to try and help me.
Dan

Getting edit value from ListView

I'm missing something here, but I've stared at it too long to see it. I've got a simple ListView, with the typical Edit/Update/Cancel buttons. I've got the following set up in my EditITemTemplate when the row goes into edit mode:
<EditItemTemplate>
<asp:Label ID="AccountIdLabel" runat="server" Text='<%#Eval("lan_id")%>' />
<asp:TextBox ID="EmployeeIdTextBox" runat="server" Text='<%#Eval("emp_id")%>' Columns="5" />
</EditItemTemplate>
At this point the user types a value in the EmployeeIdTextBox. When they press Update, it's trying to do the following:
Private Sub ListView_ItemUpdating(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.ListViewUpdateEventArgs) Handles EmployeeListView.ItemUpdating
Dim accountId = CType(EmployeeListView.EditItem.FindControl("AccountIdLabel"), Label).Text
Dim employeeId = CType(EmployeeListView.EditItem.FindControl("EmployeeIdTextBox"), TextBox).Text
UpdateMap(accountId, employeeId)
EmployeeListView.EditIndex = -1
GetData()
End Sub
The problem is that "employeeId" is coming back with the original value in the text box, not what the user entered. What am I missing?
UPDATE: Found it. As usual, caused by other code not included here in an effort to ask a simple question. :)
Found it - I had code in the ItemCommand event that was handling other events, but it was doing the GetData() at the end regardless of the command, so basically the data was being refreshed right before the ItemUpdating event fired. I tightened up ItemCommand, and it's now working as expected.
I think this is because the ItemUpdating event fires before the ListView updates the record. You probably want to put this code in the ItemUpdated event instead.
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.listview.itemupdating.aspx

Resources