ASP.Net Auto-populate field based on other fields - asp.net

I've just moved to web development and need to know how i can implement below requirement using asp.net and vb.net.
I have three fields in a form which are filled by users. Based on these three values, i need to auto-populate the 4th field. I have planned to implement this in the following way
Write a separate class file with a function to calculate the possible values for the 4th fields based on 1st 3 inputs. This function can return some where between 1-10 values. So I've decided to use drop-down for 4th field, and allow users to select the appropriate value.
Call the above function in onchange function of 3rd field and take and use the return values to populate the 4th field. I'm planning to get the return values in array field.(Does this need a post back?)
Please let me know how if there is better way to implement this.
Thanks.

You may want to consider doing this with Javascript. You could read and control the fields pretty easily with pure Javascript, or using a nice library like jQuery (my favorite). If you did it this way, no post-back would be required and the 4th field would update immediately. (Nice for your users)
You can also do it with ASP.NET for the most part. "onchange" in ASP.NET still requires Javascript as far as I know, it just does some of it for you. A post-back will definitely happen when you change something.

You need javascript or to set autopostback=true on your form elements.
From a user perspective the best thing is to use javascript to populate the field for display, BUT when the form is submitted use your backend function to validate it. This will make sure the user didn't change the value.

An easy way is to use jQuery for the UI (that way you don't have to worry about long winded javascript and deal with browser compatibility as it's already taken care of for you) and have it call to the server for the data. For the server, your easiest route is to return JSON for looping values.
Include your jQuery:
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.3/jquery.min.js"></script>
Then add in a handle for the JavaScript:
<script type="text/javascript">
function autoPopulate() {
var value1 = $('#ddl1').val();
var value2 = $('#ddl2').val();
var value3 = $('#ddl3').val();
var url = 'path/to/your/file.aspx?value1=' + value1 + '&value2=' + value2 + '&value3=' + value3;
$.getJSON(url, function(data) {
data == null ? return false : data = eval(data);
var ddl = $('#ddl4')[0];
for (i = 0; i < data.length; i++) {
var option = new Option(data[i][0], data[i][1]);
if ($.browser.msie) {
ddl.add(option);
} else {
ddl.add(option, null);
}
}
}
}
</script>
(Yes, I know I used a native loop but I'm little lazy here today :) )
Now, for your server side code you'll want your code your page to return data in the format of:
[['value1','text1'],['value2','text2'],['value3','value3']]
so something like:
<script type="vb" runat="server">
Private Sub Page_Init()
// get your data
// loop through it and add in values
// ex.
Dim result As String = "[" //start multi-dimensional array
For Each Item As String In data
result += String.Format("['{0}','{1}'],", _value, _text)
Next
result = result.SubString(0, result.Length - 1) // removes trailing comma
result += "]" // closes off m-array
Response.Write(result)
Response.Flush()
End Sub
</script>

Related

Update Javascript variable from code behin Thread

I want to implement a serverside download process which reports its progress to the client.
I defined a global variable in my .aspx site class:
Public progressStatus As Integer
Then a start a new Thread to download the images in a List, which also changes the value of the global variable:
For Each imageUrl In imageFiles
currentUrlCount = currentUrlCount + 1
indexOfUrlSplit = imageUrl.LastIndexOf("/")
localFilename = imageUrl.Substring(indexOfUrlSplit + 1)
If localFilename <> "" Then
httpClient.DownloadFile(url, localImage)
progressStatus = CInt((currentUrlCount / totalUrlCount) * 100)
End If
Next
I use the SetIntveral Javascript methods to check for the value of the global variable every 2 seconds:
var progStat;
setInterval(function() {
progStat = <%=progressStatus%>;
document.write(progStat + "\n");
}, 2000);
Through debugging I checked that the global Variable in the Code behind is calculated and changed correctly. Anyway, Javascript keeps the initial Value of 0.
I would be glad if someone could help me with that problem!
Thank you very much everybody,
Max
When you use syntax like that:
progStat = <%=progressStatus%>;
progressStatus value is retrieved once and converted to string when page is rendered. At that time value is 0. It isn't retrieved from server every time you call that script.
It means javascript function rendered on your page looks like:
progStat = 0;
When you keep calling that function multiple times client-side it does not change as page isn't re-rendered.
You need to make use of an Ajax call to retrieve the value from the server. Use the result from the call together with JQuery and then update the UI

Gridview manipulation using JQuery and JavaScript

I have an ASP.NET gridview I want to manipulate using JavaScript/JQuery. The problem I THINK I'm going to have with my approach is that the server won't have any knowledge of the rows that I am appending via gridview since the html representation of the gridview control is coupled with the object model that lives on the server. So here is what I need to do:
I need to append to the gridview when a user submits data, and submit each row in the batch of entered data to the server to be processed. Because I have other ASP.NET controls that will contain data that I want to submit, I'd like to submit all that data via a traditional postback to the server.
How do I implement this approach if possible?
If not possible, could you please explain?
Thank you very much for your help.
var queryString = "";
// This could be based on a number of different events
$('#finishButton').click(function(){
// Iterate through each input (you could add other form elements)
$('#myForm input').each(function(){
// Build your query string to post to your aspx page
queryString += $(this).attr("name") + "&" + $(this).val() + ",";
});
});
// Make sure special chars are escaped
queryString = escape(queryString);
// POST the form to your aspx page
$.ajax({
type: 'POST',
url: 'myFormProcessor.aspx',
data: queryString,
// Upon a successful POST, successHandler will be called
success: successHandler
});
// Add the new data to the grid
function successHandler(){
// Clone the last row
$('#myTable tr:last').clone(true).insertAfter('#myTable tr:last');
// Here you could just break apart the query
// string you build in the above code
// and use those values to change the values
// in the row you added to the grid
}
Make sure to unescape the query string in your aspx page, and then break it up by the delimiters you're using. I used '&' to separate key/value and commas between variables (inputs).

getting client id of a control from variable

I want the client id of an asp.net textbox control(txtTest) in javascript.But the problem here is the control id comes from a variable as shown below
var testName = 'txtTest';
var testCntrl = document.getElementById('<%=' + testName + '.ClientID %>');
But its throwing
CS1012: Too many characters in
character literal
Can any one please help....
Try this:
document.getElementById('<%=txtTest.ClientID %>');
Or more along the lines of your original example:
var testName = '<%=txtTest.ClientID %>';
var testCntrl = document.getElementById(testName);
It appears from your example that you have managed to confuse yourself over what is server side and what is client side code.
<%= aspControlID.ClientID %> is a server side control, but you are trying to pass a clientside variable name to it. By the time testName is set equal to 'txtTest' its too late, you're already on the client.
There are a number of alternatives to get the server side ClientIDs as Rick Stahl discusses.
1) You can pre-load all the control IDs that you know you're going to need like this, they query them (he uses jquery) when you need their elements.
var ids = {
txtSymbol: "#<%= txtSymbol.ClientID %>",
PageContent: "#<%= PageContainer.ClientID %>"
}
This can also be written:
var txtSymbol = document.getElementById('<%= txtSymbol.ClientID %>');
var txtBlah = document.getElementById('<%= txtBlah.ClientID %>');
2) Or, he wrote a function that will get a control for you from the clientside
function $$(id, context) {
var el = $("#" + id, context);
if (el.length < 1)
el = $("[id$=_" + id + "]", context);
return el;
}
Be aware that there are some serious caveats. This relies on JQuery, so be sure to include that library and use it like this $$('myASPControlID').val('new val'); The catch is that if you have any controls that create other controls, like listviews, repeaters, gridviews etc. Then finding a single instance of a child control will take some strategy. In that situation, this tool will only get the first instance of a repeated control.
Still, the function provides a way to solve this problem by allowing you to specify a containing element in the second field.
EDIT
Hey L G, if you really need to pass your variable from the client side, then just add the second function and a link to the JQuery library. Then you can get your control with this simple code:
var testName = 'txtTest';
var testCntrl = $$(testName);
If it is C# code (which I assume, given the compilation error), you need to surround strings with " instead of '.
' is used for char values, that can contain only one character (or two if it is an escaped one, such as '\n').
But I don't really get the connection between the compilation error and the code, since the C# compiler should not bother about the javascript code...

ICallBackEventHandler does not update controls with form values

I want to use ICallBackEventHandler however when I use it to call back to the server I find that my form control objects don't have the latest form values. Is there a way to force populate the values with the form data?
Thanks.
Have a look at http://msdn.microsoft.com/en-us/magazine/cc163863.aspx.
In short, you have to clear the variable '__theFormPostData', and call the 'WebForm_InitCallback()' before the 'CallbackEventReference' script. This updates the form values with the user input values. Something like this:
// from the above link
string js = String.Format("javascript:{0};{1};{2}; return false;",
"__theFormPostData = ''",
"WebForm_InitCallback()",
Page.GetCallbackEventReference(this, args, "CallbackValidator_UpdateUI", "null"));
You obviously still dont have the same issue but wha you need to do is recall WebForm_InitCallback() prior to your JavaScript Callback Code. This will get the page to refresh the POST values in your Request.Form object.
When you now do a PostBack the values modified during Callbacks will be available. It goes without saying they will be available during Callbacks.
etc
function SomeCode()
{
__theFormPostCollection.length = 0;
__theFormPostData = "";
WebForm_InitCallback();
ExecuteMyCallbackMethod("yaday", "yadya");
}

Ideas on making a javascript object name unique in ASP.Net?

I've created an ASP.Net user control that will get placed more than once inside of web page. In this control I've defined a javascript object such as:
function MyObject( options )
{
this.x = options.x;
}
MyObject.prototype.someFunction=function someFunctionF()
{
return this.x + 1;
}
In the code behind I've created MyObject in a startup script --
var opts = { x: 99 };
var myObject = new MyObject( opts );
When a certain button in the control is pressed it will call myObject.someFunction(). Now lets say the value of x will be 99 for one control but 98 for another control. The problem here is that the var myObject will be repeated and only the last instance will matter. Surely there's a way to make the var myObject unique using some concept I've haven't run across yet. Ideas?
Thanks,
Craig
Your Javascript like this:-
function MyObject(options) { this.x = options.x; }
MyObject.prototype.someFunction = function() { return this.x + 1; }
MyObject.create(id, options) {
if (!this._instances) this._instances = {};
return this._instances[id] = new MyObject(options);
}
MyObject.getInstance(id) { return this._instances[id]; }
Your startup javascript like this:-
MyObject.create(ClientID, {x: 99});
Other code that needs to use an instance (say in the client-side onclick event)
String.Format("onclick=\"MyObject.getInstance('{0}').someFunction()\", ClientID);
Note the low impact on the clients global namespace, only the MyObject identifier is added to the global namespace, regardless of how many instances of your control are added to the page.
If it is just one value, why not have the function take it as a parameter and build your onclick handler so that it puts the correct value in for each control. If it is more complex than that, then consider making options an array and, for each control, insert the correct options into the spot in the array that corresponds to each particular control. Then pass the proper index into the array into the function.
I do this by using ScriptManager.RegisterClientScriptBlock to register a string as a JavaScript block on the client side. I can then modify my script string using {0}, {1}..,{n} place holders to inject necessary ids. It depends on the structure of your code as to if this is the most elegant fashion, but it works in a pinch. You could then inject variable names using references to Me.ClientID.
You can make the value of "x" static and access it anywhere in the code, such as:
function MyObject( options ) { MyObject.x = options.x; }
MyObject.x = 99; // static
MyObject.prototype.someFunction = function () { return MyObject.x + 1; }
This way you can access MyObject.x anywhere in your code, even without re-instanciating MyObject.
Excellent solution Anthony. The other solutions offered were as good and I did consider them but I was looking for something a little more elegant like this solution.
Thanks!

Resources