Calling Code Behind Function and passing arguments - asp.net

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

Related

How to write a conditional that alerts a user if a text box is changed a second time

What I am trying to do is create a conditional statement that will alert the user if a text box is changed after initially filling that field.
For instance if they enter their name into the text box and then at a later point enter a different name into that text box, I want it to alert the user.
Below is my code of both the text box control as well as a .textchanged event.
Text Box Control:
<div class="txtSearch">
<asp:TextBox ID="txtSearchOC" runat="server" Width="250px" Text="" AutoPostBack="True" TabIndex="13" Font-Bold="True"
ForeColor="#822402" BorderColor="#822402" AutoCompleteType="Disabled" ClientIDMode="Static" />
</div>
.textChanged Event Code:
Protected Sub txtSearchOC_TextChanged(sender As Object, e As EventArgs) Handles txtSearchOC.TextChanged
Dim searchOCText As String = txtSearchOC.Text
Dim isTheSame As Boolean = False
If searchOCText = txtSearchOC.Text Then
isTheSame = True
End If
If isTheSame = True AndAlso searchOCText <> txtSearchOC.Text Then
Call txtSearchOC_Warning()
End If
End Sub
My thought process was to store the first name in a variable called "searchOCText" and then have a boolean that would hold true if searchOCText = txtSearchOC.Text, I would then use that boolean value to test if the text in the text box had changed, but I'm not terribly sure where to go from here as I am pretty new to programming.
So far I have tested the procedure "txtSearchOC_Warning()" and on its own it works and displays the message I am wanting to display. However when I try to call it from the TexChanged procedure nothing happens and I am at a loss as to why. So I am left to believe that the problem lies within my conditional and that I need to start digging there.
Any and all help would be greatly appreciated.
It's better to use JS to perform this validation since it's more efficient and doesn't require a PostBack to trigger. Check the following simple script:
<script>
let oldVal=document.getElementById("<%=txtSearchOC.ClientID%>").value;
function checkChange(val) {
if(oldVal!="")//To check if this change is a first time change
{
alert("The input value has changed to: " + val);
}
oldVal=val;
}
</script>
And your Text Box definition will be:
<asp:TextBox ID="txtSearchOC" runat="server"
onClientClick="checkChange(this.value)" AutoPostBack="false" ...
The problem with your approach is that searchOCText will be always equal to txtSearchOC after the PostBack. Line Dim searchOCText As String = txtSearchOC.Text
If you still want to use this approach you may store searchOCText in a Session like this:
Try
If Session("searchOCText").ToString()= txtSearchOC.Text Then
isTheSame = True
End If
Catch
End Try
Session("searchOCText")=txtSearchOC.Text
Looks like your code has some small mistakes:
TextChanged raised on programmatically setting value and any typing, every stroke. Better to use the LostFocus event.
Variable isTheSame is redundant (always True) because the event raises after text changing.
Actually, your message will never be shown when changing the user contents or not, because you compare user input with the same user input (inequality searchOCText <> txtSearchOC.Text always be False).
I think it is the simplest solution.
Public Class ExtTextBox
Inherits TextBox
Private LastUserInput As String
Protected Sub ExtTextBox_LostFocus(sender As Object, e As EventArgs) Handles Me.LostFocus
Select Case True
Case LastUserInput Is Nothing
LastUserInput = Text
Case Text <> LastUserInput
If MsgBox("Apply change?", MsgBoxStyle.YesNo Or MsgBoxStyle.Question) = MsgBoxResult.Yes Then
LastUserInput = Text
Else
Text = LastUserInput
End If
End Select
End Sub
End Class
Variable LastUserInput (initially Nothing) stores user input.
The first branch of Select Case stores the first user input in LastUserInput.
The second branch updates stored input or restored text according to user decision where the user points to any other element after any edit excluding the first one. You can put any code into the second branch to process new input.

validate a template text box with database value

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

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.

Custom Validator Not Firing (No error message, but no validation)

I have a custom validator:
<asp:CustomValidator ID="QuestionValidator" runat="server" ErrorMessage="Please select an option" ClientValidationFunction="QuestionValidator_ServerValidate" OnServerValidate="QuestionValidator_ServerValidate" ValidateEmptyText="true"></asp:CustomValidator>
I have a list of questions provided by a datalist, which I need to ensure a user selects an answer to each question. I then have my validation functions:
Protected Sub QuestionValidator_ServerValidate(ByVal source As Object, ByVal args As ServerValidateEventArgs)
Dim SelectedItem As Boolean = False
For Each c As Control In Page.Master.FindControl("form1").Controls
If TypeOf c Is RadioButton Then
Dim rb As RadioButton = DirectCast(c, RadioButton)
If rb.GroupName = "AnswerOptions" AndAlso rb.Checked = True Then
SelectedItem = True
End If
End If
Next
args.IsValid = SelectedItem
End Sub
<script type="text/javascript" language="javascript">
function QuestionValidator_ServerValidate() {
return true;
}
</script>
When I run the page, there is no validation and no error message. Please can you point out where I am going wrong, I'm suspicious it is at Page.Master.FindControl("form1").Controls.
I have previously done such validation by looping through controls via form1.controls but this is unavailable as the page uses a form passed down via the master page.
There could be a flaw in your code. Because as per the logic if out of 50 radio buttons on your page even if just one is selected your validation will pass. Also the groupname for all the RBs is same for each item. Not sure if ASP.NET renames those and if not then all RBs with be grouped into one for all the questions.
For the looping part you can loop through DataList.Items collection instead of looping through all controls on the form:
Dim item As DataListItem
For Each item In DataList1.Items
Dim ctrl As Control
For Each ctrl In item.Controls
'do your rb state check here
Next ctrl
Next item
I would try looping through either "Page.NamingContainer" or "Page.Controls" and see how that goes.
Maybe I missed something, but shouldn't You also set property ControlToValidate="ID_of_the_control_to_validate" in the custom validator?
I think you need to give ValidationGroup for the CustomValidator and all the Controls Involved in the Validaiton process

ASP.NET Dynamic User Controls

I'm sure this question has been asked a million times, however I haven't been able to find an answer that solves my problem.
I am programmatically adding some custom user controls to a PlaceHolder which I have on a simple aspx page. All of the user controls Postback's work correctly except for one which has a Gridview on it.
For some reason any postback that gets fired from within this control, does not call the specified event on the first click, however all future clicks it will work fine. I have no idea why this is the case, but many solutions I have found, suggest adding an ID to the ascx User Control, however this doesn't work in my case.
I've taken a look at the source file for the page that gets generated before and after the first click, javascript used for calling the postback changes, i.e
Before first click: onclick="javascript:__doPostBack('tmpControlID$sgvPrimaryEmploymentHistory','Select$0')"
After first click: onclick="javascript:__doPostBack('OFFHome1$tmpControlID$sgvPrimaryEmploymentHistory','Select$0')"
OFFHome1 is the parent user control which exists on the aspx page. All other controls are added to a placeholder in this control, i.e.
<%# Control Language="vb" AutoEventWireup="false" CodeBehind="OFFHome.ascx.vb" Inherits="UmbracoUserControls.OFFHome" %>
<asp:PlaceHolder ID="phOFFSection" runat="server"></asp:PlaceHolder>
Nothing to complicated. Then in the code behind the controls are loaded into the placeholder using the following:
Private Sub LoadNextOFFStep()
Dim ControlName As String = "TestControl.ascx"
phOFFSection.Controls.Clear()
If ControlName IsNot Nothing AndAlso ControlName <> String.Empty Then
Dim NewControl As Object = LoadControl(ControlName)
With NewControl
.ID = USERCONTROLNAME
Dim StepCompleted As Boolean = .FillControl()
If StepCompleted Then
Exit Sub
End If
Dim AllowSkip As Boolean = .AllowSkip()
btnSkip.Visible = AllowSkip
End With
phOFFSection.Controls.Add(NewControl)
End If
End Sub
Again, nothing overly complicated. The USERCONTROLNAME is just a const with the value "tmpControlID" in it.
The control that is giving me trouble is a little complicated, I was originally using a custom GridView control that we have created, but have removed it and replaced it with the standard asp one to see if the problem still occurs, and it does.
Any button, on control which fires off a postback will fail the first time, and all future click will work correctly. On the first click the Page_Load event will get called, but that is it.
What am I doing wrong??
After far too much time spent on this, I have finally worked it out.
It was to do with the order of events, however just not where I had thought. The FillControl function was getting called before User Control had been added to the PlaceHolder. I changed this so that it gets called after the User Control was added to the PlaceHolder and now it works first time.
Basically the code looks like this now:
Private Sub LoadNextOFFStep()
Dim ControlName As String = "TestControl.ascx"
phOFFSection.Controls.Clear()
If ControlName IsNot Nothing AndAlso ControlName <> String.Empty Then
Dim NewControl As Object = LoadControl(ControlName)
With NewControl
.ID = USERCONTROLNAME
Dim AllowSkip As Boolean = .AllowSkip()
btnSkip.Visible = AllowSkip
End With
phOFFSection.Controls.Add(NewControl)
Dim StepCompleted As Boolean = CType(phOFFSection.Controls(0), Object).FillControl()
If StepCompleted Then
LoadNextOFFStep()
Exit Sub
End If
End If
End Sub
Thanks for everyone's help.
Well... the answer to the first question is simple: It fails the first time because the ID of the control (or rather, in the postback script) is different on subsequent page loads. It works on subsequent clicks because the control ID stays the same.
Now as to WHY that is... much tougher! But probably something to do with the order of operations here.
Try explicitly setting the NamingContainer value for NewControl:
With NewControl
.NamingContainer = OffHomeOne; // whatever
.ID = USERCONTROLNAME

Resources