Executing VB via JavaScript

K

Kirk

Let me start by saying that I am a complete idiot when it comes to
JS. However, I need help with something that apparently can only be
done this way.

I am using an ASP.NET AJAX control (ValidatorCallout) that requires
client-side validation to work with a custom validator I added. This
is an example of some code that works:

<asp:CustomValidator ID="CV_PartNumberExists" runat="server"
OnServerValidate="PrimeNumberCheck"
ClientValidationFunction="CheckPrime"
ControlToValidate="PartNumberText" ErrorMessage="b><br />A Part
Number is required."></asp:CustomValidator>
<script language="JavaScript">
<!--
function CheckPrime(sender, args)
{
var iPrime = parseInt(args.Value);
var iSqrt = parseInt(Math.sqrt(iPrime));

for (var iLoop=2; iLoop<=iSqrt; iLoop++)
if (iPrime % iLoop == 0)
{
args.IsValid = false;
return;
}

args.IsValid = true;
}


This is code I borrowed from another site to test this method - and it
works. My problem is that I need the JS to execute a VB function in
my project and I don't know how to do that. I want to do something
like:

function CheckValue(sender, args)
{
var sPartnumber = String(args.Value);
if FindExistingPN(sPartNumber)
{
args.IsValid = false;
return;
}
args.IsValid = true;
}

....where FindExistingPN is a funciton in my VB class. I have seen
some other posts about this, but none of them really gave me any
sample code that I could run. As I mentioned earlier, my JS skills
are lacking, so I am unable to create this myself.

Anyway, I would greatly appreciate any suggestions or sample code.
Thank you!
 
J

Jeremy

Kirk said:
Let me start by saying that I am a complete idiot when it comes to
JS.

In the words of Jamie Hyneman, "Well *there's* your problem!"

I kid, I kid.
My problem is that I need the JS to execute a VB function in
my project and I don't know how to do that. I want to do something
like:

function CheckValue(sender, args)
{
var sPartnumber = String(args.Value);
if FindExistingPN(sPartNumber)
{
args.IsValid = false;
return;
}
args.IsValid = true;
}

...where FindExistingPN is a funciton in my VB class.

Your problem is that you're not differentiating in your head between
client-side code (JS) and server-side code (VB) in this case. The VB
you want to run is server-side, and you want to run it from client-side
code. Without some help from an AJAX framework, this is not possible to
do as seamlessly as your example.

What you need to do is send the parameter (sPartNumber) to the server in
an asynchronous request (a.k.a. AJAX, although you need not necessarily
use the XML that forms the X of this acronym), along with some sort of
meta-data that tells the server to pass it to the FindExistingPN
function and spit out the result. Then, you wait for that result,
interpret it, and decide whether or not to execute the code inside your
if-block.

In order to do this, you are going to have to wrap your head around
asynchronous operation, because your JS code will not (or at least,
should not - although it is possible) block until the result of
FindExistingPN is known. So it will have to look more like this:

Instead of
if(FindExistingPN(sPartNumber)
{
//do stuff A
return;
}
//do stuff B

you would need

var async = new XMLHttpRequest();
async.open("POST", '/special/url', true);
async.setRequestHeader('Content-Type',
'application-x-www-form-urlencoded');
async.onreadystatechange = function()
{
if(async.readyState == 4)
{
if(async.responseText == 'true')
{
//do stuff A
}
else
{
//do stuff B
}
}
}
async.send('sPartNumber=' + escape(sPartNumber));


What happens here is that you have a special URL, '/special/url', which
picks up the POST variable 'sPartNumber' and performs the check. It
prints out plain text of 'true' or 'false' depending on the result.
This gets passed into the anonymous function() which performs the stuff
you want depending on the result of the check.

The c.l.javascript FAQ has pointers to some nice AJAX resources, if you
want to pursue this option (see http://www.jibbering.com/faq/#FAQ4_44).
You could use a framework instead (google it), but it's a good idea to
learn how it works if you want to be a good javascript developer.

Apologies for the long-winded reply.

Jeremy
 
D

dogatemycomputer

Apologies for the long-winded reply.

Jeremy


I don't think we have enough "long winded" responses in many of the
technical newsgroups. I am not the original poster but I am
personally learning C++ and JS myself. Life would be much easier if
many of the responses were better documented. It would save on repeat
posts and give the rest of us some appreciation for "why" the problem
exists not to mention the *correct* resolution. :)

So.. Please keep up the long winded responses. We need more of them!
 
K

Kirk

In the words of Jamie Hyneman, "Well *there's* your problem!"

I kid, I kid.








Your problem is that you're not differentiating in your head between
client-side code (JS) and server-side code (VB) in this case. The VB
you want to run is server-side, and you want to run it from client-side
code. Without some help from an AJAX framework, this is not possible to
do as seamlessly as your example.

What you need to do is send the parameter (sPartNumber) to the server in
an asynchronous request (a.k.a. AJAX, although you need not necessarily
use the XML that forms the X of this acronym), along with some sort of
meta-data that tells the server to pass it to the FindExistingPN
function and spit out the result. Then, you wait for that result,
interpret it, and decide whether or not to execute the code inside your
if-block.

In order to do this, you are going to have to wrap your head around
asynchronous operation, because your JS code will not (or at least,
should not - although it is possible) block until the result of
FindExistingPN is known. So it will have to look more like this:

Instead of
if(FindExistingPN(sPartNumber)
{
//do stuff A
return;
}
//do stuff B

you would need

var async = new XMLHttpRequest();
async.open("POST", '/special/url', true);
async.setRequestHeader('Content-Type',
'application-x-www-form-urlencoded');
async.onreadystatechange = function()
{
if(async.readyState == 4)
{
if(async.responseText == 'true')
{
//do stuff A
}
else
{
//do stuff B
}
}
}
async.send('sPartNumber=' + escape(sPartNumber));

What happens here is that you have a special URL, '/special/url', which
picks up the POST variable 'sPartNumber' and performs the check. It
prints out plain text of 'true' or 'false' depending on the result.
This gets passed into the anonymous function() which performs the stuff
you want depending on the result of the check.

The c.l.javascript FAQ has pointers to some nice AJAX resources, if you
want to pursue this option (seehttp://www.jibbering.com/faq/#FAQ4_44).
You could use a framework instead (google it), but it's a good idea to
learn how it works if you want to be a good javascript developer.

Apologies for the long-winded reply.

Jeremy- Hide quoted text -

- Show quoted text -

Wow. I think my brain just imploded. You JS guys are paid WAY too
little.

I understand (in concept) what you described, so I will start
experimenting. Thanks for the excellent reply & detailed info! I
will post back with my results.
 
K

Kirk

Wow. I think my brain just imploded. You JS guys are paid WAY too
little.

I understand (in concept) what you described, so I will start
experimenting. Thanks for the excellent reply & detailed info! I
will post back with my results.- Hide quoted text -

- Show quoted text -

OK, I am once again banging my head against the wall. Here is what I
have so far.

I created a page that uses the passed parameter to determine what to
put in the response. This looks like:

'Get the passed parameter from the page
If Not (Request.Params("sPartNumber") Is Nothing) Or
(Request.Params("sPartNumber") = "") Then
'A value was passed, check it...
Dim PartNumber As String = Request.Params("sPartNumber")

If FindExistingPN(PartNumber) Then
'Part number was found
Me.Page.Response.Write("true")
Else 'Part number was not found
Me.Page.Response.Write("false")
End If
End If

This works, in the sense that if I open the page like
this :"PartExistCheck.aspx?sPartNumber=230-001", it outputs True or
False based on the value passed.

Your code did just as you promised, but I am still mucking something
up. When the validation runs, I can set a breakpoint in the VB code
and see that it is executing (yay!). However, the value is not being
passed - it always comes back as [nothing]. Am I looking at the wrong
parameter?

function CheckPart(sender, args)
{
var async = new XMLHttpRequest();
async.open("POST", 'PartExistCheck.aspx', true);
async.setRequestHeader('Content-Type',
'application-x-www-form-urlencoded');
async.onreadystatechange = function()
{
if(async.readyState == 4)
{
if(async.responseText == 'true')
{
args.IsValid = false;
return;
}
else
{
args.IsValid = true;
}
}
}
async.send('sPartNumber=' + escape('230-001'));
}

I hard coded the part number ("230-001") because I kept getting an
undefined variable error (maybe we can discuss that later). Also - I
can't seem to get the function to return False in the JS (the
args.IsValid section). I set them both to False to try and force it
to trigger my validation, but it never fires. Again, any suggestions?

Thank you very much for your help!
 
J

Jeremy

Kirk said:
OK, I am once again banging my head against the wall. Here is what I
have so far.

I created a page that uses the passed parameter to determine what to
put in the response. This looks like:

'Get the passed parameter from the page
If Not (Request.Params("sPartNumber") Is Nothing) Or
(Request.Params("sPartNumber") = "") Then

This isn't directly related to your JS question (and I haven't
programmed in VB for over a decade, so I could be wrong), but it seems
to me that this ought to be:

If Not(Request.Params("sPartNumber") Is Nothing Or
Request.Params("sPartNumber") = "") Then

or

If Not(Request.Params("sPartNumber") Is Nothing) And
Not(Request.Params("sPartNumber") = "") Then

Otherwise your logic will always enter the If-block when
Request.Params("sPartNumber") = "" (which is probably the opposite of
what you want).
<snip>

This works, in the sense that if I open the page like
this :"PartExistCheck.aspx?sPartNumber=230-001", it outputs True or
False based on the value passed.

Your code did just as you promised, but I am still mucking something
up. When the validation runs, I can set a breakpoint in the VB code
and see that it is executing (yay!). However, the value is not being
passed - it always comes back as [nothing]. Am I looking at the wrong
parameter?

function CheckPart(sender, args)
{
var async = new XMLHttpRequest();
async.open("POST", 'PartExistCheck.aspx', true);
async.setRequestHeader('Content-Type',
'application-x-www-form-urlencoded');
async.onreadystatechange = function()
{
if(async.readyState == 4)
{
if(async.responseText == 'true')
{
args.IsValid = false;
return;
}
else
{
args.IsValid = true;
}
}
}
async.send('sPartNumber=' + escape('230-001'));
}

<snip>


The thing you are missing is the principle of asynchronous operation.
By the time the response comes back and the anonymous function() is
executed, you are no longer in the CheckPart function, in terms of
execution flow. That function has already returned (nothing, in this
case) and the program has moved on.

Here is the sequence of events in this case:

1. CheckPart is called.

2. CheckPart sends off HTTP request.

3. CheckPart returns nothing. "args" reference parameter is untouched
at this point.

4. Whatever function called CheckPart sees that the call did nothing.
It becomes distraught and goes off to the pub.

5. An unspecified amount of time passes - probably a few hundred
miliseconds.

6. Anonymous function() is called. outer if-block is entered.

7. args.IsValid is set to either true or false.

8. Anonymous function() returns nothing. "args" is now altered in the
desired sense, but the function that called CheckPart to begin with is
already off at the pub having a drink and can't do anything about it.


Unfortunately, you have just touched upon one of the most confusing
aspects of AJAX (asynchronous operation) and one of the most confusing
aspects of the javascript language (scoping) at the same time!

The key point here is that you simply must not look at the inner
function() as something that will be executed immediately*. It will be
executed (hopefully) at some point in the future, so instead of
monkeying with local data, which will be passed back to another function
that does some voodoo, it should use the information it has to do the
voodoo itself. I don't know what your code does after CheckPart
returns, so I can't really help you with that part. But chances are you
will need a pretty major restructuring of your javascript, consisting
of taking everything that CheckPart's caller was supposed to do after
CheckPart returned, and either doing it in your anonymous function(), or
putting it in a separate function that gets called by the anonymous
function.

If you need an example of converting a synchronous call to an
asynchronous one, I'll post one (but first you should take a crack at it
and see what you can do).

Jeremy

*It is actually *possible* to make your request operate in a synchronous
fashion, which would make your code here work. HOWEVER, this is
generally accepted to be a Real Bad Idea and a cardinal programming sin.
I'll tell you how to do it, but you shouldn't. Replace the last
parameter to async.open - change true to false. Now your request will
block until it is complete. The problem is, this could potentially be
forever (if the server dies, for example) and it will freeze up the browser.
 
K

Kirk

Kirk said:
OK, I am once again banging my head against the wall. Here is what I
have so far.
I created a page that uses the passed parameter to determine what to
put in the response. This looks like:
'Get the passed parameter from the page
If Not (Request.Params("sPartNumber") Is Nothing) Or
(Request.Params("sPartNumber") = "") Then

This isn't directly related to your JS question (and I haven't
programmed in VB for over a decade, so I could be wrong), but it seems
to me that this ought to be:

If Not(Request.Params("sPartNumber") Is Nothing Or
Request.Params("sPartNumber") = "") Then

or

If Not(Request.Params("sPartNumber") Is Nothing) And
Not(Request.Params("sPartNumber") = "") Then

Otherwise your logic will always enter the If-block when
Request.Params("sPartNumber") = "" (which is probably the opposite of
what you want).




This works, in the sense that if I open the page like
this :"PartExistCheck.aspx?sPartNumber=230-001", it outputs True or
False based on the value passed.
Your code did just as you promised, but I am still mucking something
up. When the validation runs, I can set a breakpoint in the VB code
and see that it is executing (yay!). However, the value is not being
passed - it always comes back as [nothing]. Am I looking at the wrong
parameter?
function CheckPart(sender, args)
{
var async = new XMLHttpRequest();
async.open("POST", 'PartExistCheck.aspx', true);
async.setRequestHeader('Content-Type',
'application-x-www-form-urlencoded');
async.onreadystatechange = function()
{
if(async.readyState == 4)
{
if(async.responseText == 'true')
{
args.IsValid = false;
return;
}
else
{
args.IsValid = true;
}
}
}
async.send('sPartNumber=' + escape('230-001'));
}

The thing you are missing is the principle of asynchronous operation.
By the time the response comes back and the anonymous function() is
executed, you are no longer in the CheckPart function, in terms of
execution flow. That function has already returned (nothing, in this
case) and the program has moved on.

Here is the sequence of events in this case:

1. CheckPart is called.

2. CheckPart sends off HTTP request.

3. CheckPart returns nothing. "args" reference parameter is untouched
at this point.

4. Whatever function called CheckPart sees that the call did nothing.
It becomes distraught and goes off to the pub.

5. An unspecified amount of time passes - probably a few hundred
miliseconds.

6. Anonymous function() is called. outer if-block is entered.

7. args.IsValid is set to either true or false.

8. Anonymous function() returns nothing. "args" is now altered in the
desired sense, but the function that called CheckPart to begin with is
already off at the pub having a drink and can't do anything about it.

Unfortunately, you have just touched upon one of the most confusing
aspects of AJAX (asynchronous operation) and one of the most confusing
aspects of the javascript language (scoping) at the same time!

The key point here is that you simply must not look at the inner
function() as something that will be executed immediately*. It will be
executed (hopefully) at some point in the future, so instead of
monkeying with local data, which will be passed back to another function
that does some voodoo, it should use the information it has to do the
voodoo itself. I don't know what your code does after CheckPart
returns, so I can't really help you with that part. But chances are you
will need a pretty major restructuring of your javascript, consisting
of taking everything that CheckPart's caller was supposed to do after
CheckPart returned, and either doing it in your anonymous function(), or
putting it in a separate function that gets called by the anonymous
function.

If you need an example of converting a synchronous call to an
asynchronous one, I'll post one (but first you should take a crack at it
and see what you can do).

Jeremy

*It is actually *possible* to make your request operate in a synchronous
fashion, which would make your code here work. HOWEVER, this is
generally accepted to be a Real Bad Idea and a cardinal programming sin.
I'll tell you how to do it, but you shouldn't. Replace the last
parameter to async.open - change true to false. Now your request will
block until it is complete. The problem is, this could potentially be
forever (if the server dies, for example) and it will freeze up the browser.- Hide quoted text -

- Show quoted text -

Jeremy,

Thanks for the detailed explanation. You are correct - I really need
some more education on these methods before I get this deep into these
issues. I appreciate your warning about doing things the wrong way
just to get things working. I will research the techniques you
described further (you have given me some good buzz words to Google).

Thank you again for all of your help!
 
D

Dr J R Stockton

In comp.lang.javascript message <[email protected]
Let me start by saying that I am a complete idiot when it comes to
JS.
...
...
var iSqrt = parseInt(Math.sqrt(iPrime));


The second quote above proves the correctness of the first one.

IMHO, your fundamental problem is that you are trying to run before you
can walk.

You need to take the time to understand the fundamentals of the language
before attempting anything more complex; the above shows that you have
not yet understood Javascript variable types.

When posting, please do not let your posting agent line-wrap the code;
manually wrap at about 72 characters, re-testing before you post. If
you will be asking here often, write within 72 characters per line.



In your primality checking, there's no need to test any even divisor
other than two; try two; then start at three & step in twos. Consider
the Sieve of Eratosthenes.

IMHO, if iPrime cannot be too big and/or if repeated tests are to be
done, it could be worth generating a list of the smaller primes and
test-dividing only by those. The largest number that can be held
exactly (in the usual manner) is 2^53, so you only need, at most, primes
up to 94906265. If iPrime <= 10^12, you only need the 78498 primes
below 10^6, which can certainly be handled (I just did).

<URL:http://www.merlyn.demon.co.uk/js-misc1.htm>, upgraded to count.

It's a good idea to read the newsgroup c.l.j and its FAQ. See below.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top