Reputation: 881
I have 50 text boxes on this form. They are all for inputting quantities of each item for purchase on our website. Like this:
My intent is to use a TextChanged
event or an OnBlur
event in the VB CodeBehind to run through and tabulate the values, and keep a running total of the cost.
I am using the <asp:textbox...>
format, not the <input type="text"...>
format.
I expect it would be some method of adding an event handler that points to the sub that runs the calculations, but it seems like I can't nail down the proper code.
The specific process, thus far, is this:
*I did it this way only temporarily. Eventually it will find those prices inside a database table, but I haven't set it up yet.
I would like to use that same loop to identify the text boxes and create an event handler for each of them, all pointing to the same sub. It'd be easier than just adding a list of "handles" clauses to one event handler. What I am seeing in my searches so far has been dynamically creating the text box and adding the handler. But the textbox is already there, I only need to add the handlers.
Is this doable? Or is there a better way?
Upvotes: 1
Views: 691
Reputation: 1504
This should be a good little template for you to review.
We're essentially using an XmlHttpRequest object to post data to a generichandler page. The XHR object responds with a status and the responseText.
<%@ Page Language="vb" AutoEventWireup="false" CodeBehind="Form.ProductPage.aspx.vb" Inherits="TestWebApplication.Form_ProductPage" %>
<!DOCTYPE html>
<html>
<head>
<title></title>
<script type="text/javascript">
var ProductManager = {
'post': function(data, fnSuccessCallback, fnFailCallback) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange = function() {
if (xmlhttp.readyState==4 && xmlhttp.status==200){
fnSuccessCallback(xmlhttp.responseText);
}
else {
if (!(fnFailCallback == null)) {
fnFailCallback();
}
}
}
xmlhttp.open("POST","Handler.Products.ashx", true);
xmlhttp.send(data);
},
'label': null,
'textbox': null,
'onBlurHandler':function(e) {
e.preventDefault();
//update the static datado an ajax post, and update total cost
var data = {
'product' : e.target.parentElement.querySelector('span').innerText,
'quantity' : e.target.value
};
ProductManager.post(data, function(result){
var elm = document.getElementById('debugWindow');
elm.innerHTML += '<br />' + result;
});
},
'onChangeHandler':function(e) {
e.preventDefault();
},
'onKeyPressHandler':function(e) {
//e.preventDefault();
},
'init': function() {
ProductManager.label = document.querySelectorAll('.product-wrapper>span');
ProductManager.textbox = document.querySelectorAll('.product-wrapper>input');
for (i = 0; i < ProductManager.textbox.length; i++) {
ProductManager.textbox[i].addEventListener('blur', ProductManager.onBlurHandler, false);
ProductManager.textbox[i].addEventListener('change', ProductManager.onChangeHandler, false);
ProductManager.textbox[i].addEventListener('keypress', ProductManager.onKeyPressHandler, false);
}
}
}
</script>
</head>
<body>
<div id="content-wrapper">
<div class="product-wrapper">
<span runat="server" id="lblProduct1Label"></span>
<input runat="server" type="text" id="tbProduct1Quantity" value="0" /></div>
<div class="product-wrapper">
<span runat="server" id="lblProduct2Label"></span>
<input runat="server" type="text" id="tbProduct2Quantity" value="0" /></div>
<div class="product-wrapper">
<span runat="server" id="lblProduct3Label"></span>
<input runat="server" type="text" id="tbProduct3Quantity" value="0" /></div>
<div class="product-wrapper">
<span runat="server" id="lblProduct4Label"></span>
<input runat="server" type="text" id="tbProduct4Quantity" value="0" /></div>
<div class="product-wrapper">
<span runat="server" id="lblProduct5Label"></span>
<input runat="server" type="text" id="tbProduct5Quantity" value="0" /></div>
<div class="product-wrapper">
<span runat="server" id="lblProduct6Label"></span>
<input runat="server" type="text" id="tbProduct6Quantity" value="0" /></div>
<div class="product-wrapper">
<span runat="server" id="lblProduct7Label"></span>
<input runat="server" type="text" id="tbProduct7Quantity" value="0" /></div>
<div class="product-wrapper">
<span runat="server" id="lblProduct8Label"></span>
<input runat="server" type="text" id="tbProduct8Quantity" value="0" /></div>
<div class="product-wrapper">
<span runat="server" id="lblProduct9Label"></span>
<input runat="server" type="text" id="tbProduct9Quantity" value="0" /></div>
<div class="product-wrapper">
<span runat="server" id="lblProduct10Label"></span>
<input runat="server" type="text" id="tbProduct10Quantity" value="0" /></div>
<div class="product-wrapper">
<span runat="server" id="lblProduct11Label"></span>
<input runat="server" type="text" id="tbProduct11Quantity" value="0" /></div>
<div class="product-wrapper">
<span runat="server" id="lblProduct12Label"></span>
<input runat="server" type="text" id="tbProduct12Quantity" value="0" /></div>
</div>
<div id="debugWindow">
</div>
<script>
ProductManager.init();
</script>
</body>
</html>
Public Class Form_ProductPage
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
For Each InputControl As HtmlInputText In Me.Controls.OfType(Of HtmlInputText).ToList
InputControl.Value = "0"
Next
Dim I As Integer = 0
For Each LabelControl As HtmlGenericControl In Me.Controls.OfType(Of HtmlControls.HtmlGenericControl).ToList
LabelControl.InnerHtml = "Product " & I
I += 1
Next
End If
End Sub
End Class
Imports System.Web
Imports System.Web.Services
Public Class Handler_Products
Implements System.Web.IHttpHandler
Sub ProcessRequest(ByVal context As HttpContext) Implements IHttpHandler.ProcessRequest
context.Response.ContentType = "text/plain"
context.Response.Write("Hello World!")
End Sub
ReadOnly Property IsReusable() As Boolean Implements IHttpHandler.IsReusable
Get
Return False
End Get
End Property
End Class
Note: The context exposes the HttpRequest object and HttpResponse object. you'll use these objects to determine
Among other possible validation and handling methods.
This is also a good area to query your database. Log/Update user session/activity details.
Upvotes: 1
Reputation: 181
I don't write or maintain any web applications.
Based on your question, This is what I envision if I had to write something similar for a desktop app.
Hopefully it will give you some ideas, and best of luck!
Option Strict On
Public Class MyItem
Public Property ItemID As Integer
Public Property Value As Decimal
End Class
Public Class Form1
Private _MyItemList As New List(Of MyItem)
Public Sub New()
' This call is required by the designer.
InitializeComponent()
'1, Update the tag property for each text box you need to identify on the form
'2, Instead of using an array. Populate the _MyItemList when you load the file
'3, Loop through the controls list
Me.Controls.OfType(Of TextBox).ToList.ForEach(Sub(_textBox)
If _textBox.Tag Is Nothing OrElse Not IsNumeric(_textBox.Tag) Then Exit Sub 'stop and loop to the next textbox
Dim _textboxID As Integer = CInt(_textBox.Tag)
'I like to get a list so I can check for duplicates
'You could use Dim _item As MyItem = _MyItemList.SingleOrDefault(Function(item) item.ItemID = _textboxID)
Dim _item As List(Of MyItem) = _MyItemList.Where(Function(item) item.ItemID = _textboxID).ToList
'Validate item
If _item Is Nothing Then Exit Sub 'Or throw an "unable to locate item" exception?
If _item.Count > 1 Then Throw New Exception("Duplicate items found for ID: " & _item(0).ItemID.ToString)
'You could add event handlers here
AddHandler _textBox.TextChanged, AddressOf TextValueChanged
AddHandler _textBox.KeyUp, AddressOf TextKeyPress
_textBox.Text = _item(0).Value.ToString 'NOTE: The text changed event will fire. Move this line above the AddHandler if this is not desired
End Sub)
End Sub
Private Sub TextValueChanged(sender As Object, e As EventArgs)
'do something
End Sub
Private Sub TextKeyPress(sender As Object, e As KeyEventArgs)
'do something
End Sub
End Class
Upvotes: 0