I have a VB.net class registered for COM interop which I'm instantiating within an HTML page using the following code:
<script type="text/javascript">
var MyClass = new ActiveXObject("Namespace.TestClass");
</script>
I can call methods on it just fine, but suppose I want to set a javascript function as a property, like so:
MyClass.TestFunction = function () { alert("It worked!"); }
How would I set my vb.net code up to be able to fire that function? This is how MSXML works in javascript for XMLHttpRequest objects, you can set
XHR.onreadystatechange = function () {}
I'm looking for a similar implementation in my class.
You have to expose a COM event, and assign the JavaScript method to that event. This way, when you invoke the event in your code, the JavaScript method will be called.
Example -
C# Code
[ComVisible(false)]
public delegate void OperationCompleted(string message); //No need to expose this delegate
public event OperationCompleted OnOperationCompleted;
if(OnOperationCompleted != null)
OnOperationCompleted("Hello World!");
JavaScript
comObject.OnOperationCompleted = function(message) { alert(message); }
Note: I have done this before. And I guess there was some COM related error. To resolve it I had to attach some attribute somewhere in the code (I don't remember it exactly right now). But you'll be able to figure it out or google it.
After trying for a while, we managed to figure out a solution that worked pretty well. Since we're setting a javascript function to the property, all the properties and methods on that function are made available to the VB.net, including the javascript standard methods, call and apply:
(function () { alert("Hello"); }).call();
The solution was to just invoke the call method in the VB.net code and it seems to work pretty well.
Related
I have plenty of pages on my website with javascript embeded in them.
alert() which is a javascript function has been used in all my scripts atleast once. I want to use custom alert box which will render same in all the browser.
I can define my own function like
function customAlert()
{
// Code goes here.
}
But have to replace alert() withcustomAlert() in all my web pages which is a time consuming process.
Instead can't we just modify native alert function accordingly and it reflects the same as in all browsers.
I think we can't use this
function alert()
{
// Code goes here.
}
because alert is a reserved javascript word for function name.
If there is a better way for implementing the same with different technique, then feel free to answer.
I hate to use jquery or any other frameworks library so please answer regarding pure javascript.
The alert is a property of the global window object, thus you can override it in the following way:
window.alert = function (message){
//do your code
};
and then use it the way you used it before:
alert('hi');
I'm trying to test a JavaScript function nested within a jQuery function using Jasmine in a Rails application as follows:
jQuery (function () {
var javascriptFunction = function () {
...functionality being tested...
}
}
When I run the Jasmine test, I get the following error: "ReferenceError: Can't find variable: javascriptFunction"
If I place the JavaScript function outside of the jQuery function, I no longer receive that error; however, that JavaScript function needs to remain within the jQuery function in order for the rest of the application to work.
Is there a way to specify to Jasmine to look for the JavaScript function within the jQuery function?
Ok so now I understand what you are trying to achieve.
There is no way to test what you have done as it is anonymous as you describe in your comments. The best way here is to add that code as a function somewhere. Could be on the window, or preferably on some other class somewhere. You can then test the outcome of calling your function at any point.
The JQuery ready function you are using is really just a way of starting your application. It says 'ok things are ready lets go'. In testing you are wanting that to happen and be repeatable so you can't rely on JQuery to do this.
//Current working version
function doTheThing(){
if ($("#isac").length && $("#isac")[0].checked) {
$(".nested-form-container").show();
enableGraduatedCheckbox();
} else {
$(".nested-form-container").hide();
}
}
jQuery (function () {
doTheThing();
}
Here is a similar discussion around the testability of what you are trying to do and the same suggestions. https://softwareengineering.stackexchange.com/questions/204389/how-to-test-functions-or-the-code-inside-document-ready-using-jasmine
i've developed a c# Library, registered as COM component. Now i need to import the ActiveX created into a html page with Javascript to use the ActiveX function. All is fine except for Callback, probably i lack in knowledge in Javascript but i'm still not able to use properly Callback. I've searched many example but some are too much deep for my objective and other one can't clear the point, so here the question.
I will explain myself:
Thi is the Event in the ActiveX component
public delegate void ButtonEvent(object sender, SignEventArgs e);
public event ButtonEvent ButtonSignOk;
This is the snippet of my Javascript
try {
var Lib = new ActiveXObject("AGI.GraphometricLib");
Lib.Initializer();
Lib.addEventListener('ButtonSignOk', OnOkHandler, false);
} catch (ex) {
alert("Error: " + ex.message);
}
function OnOkHandler(arg1, arg2){
alert("Pressed!");
}
Obviously the addEventListener return an error.
Error: Object doesn't support property or method 'addEventListener'
How can i properly setup a javascript callback for that event defined in the ActiveX ?
Event handlers for ActiveX objects can be written with the following syntax:
function Lib::ButtonSignOk(sender, e) {
alert("Pressed!");
}
However, there is a catch. The nature of Javascript is that
function declarations are evaluated before anything else in the file
this function declaration is interpreted as adding an event handler to the object referred to by Lib, which doesn't exist at the beginning of the file.
The solution is to force the function declaration to be evaluated after the variable initialization, e.g.:
var Lib = new ActiveXObject("AGI.GraphometricLib");
Lib.Initializer();
(function() {
function Lib::ButtonSignOk(sender, e) {
alert('Pressed!');
}
})();
See here for a full writeup, and here for a library I've written that makes this a little easier.
I'm ("still", for those who read my previous posts) working on an ICEFaces web application.
This question can be interpreted as general Javascript question, so read on if you don't know much about ICEFaces
I need to extend the behaviour of the classes created by ICEFaces Javascript framework, in particular ToolTipPanelPopup.
I cannot modify the source code of the library (otherwise I would have achieved my goal).
This is how ICEFaces defines the class (much like jQuery and other Javascript frameworks).
ToolTipPanelPopup = Class.create({
[...]
showPopup: function() {
[...]
},
updateCordinate: function(event) {
[...]
},
[...]
});
My question is very simple
How do I extend the behaviour of showPopup() function in order to run my custom function at the end of it?
I mean something like following Java example code that supposes inheritance
public void ShowPopup()
{
super.ShowPopup();
customMethod();
}
Something like this should work:
var original = ToolTipPanel.showPopup;
ToolTipPanel.showPopup = function() {
original(); //this is kind of like the call to super.showPopup()
//your code
};
I tried out this trivial example in Firebug, and it seems to work:
var obj = {
func: function() {
console.log("foo");
}
};
obj.func();
var original = obj.func;
obj.func = function() {
original();
console.log("bar");
};
obj.func();
Firebug output:
foo
foo
bar
So what's happening here is that you're saving a reference to the original showPopup function. Then you're creating a closure and assigning it back to showPopup. The original showPopup is not lost, because you still have a reference to it in original. In the closure, you call the function that original references, and then you have your own code. Just swap around the order if you want to do something first before you call original. Since you're using a closure, original is lexically bound to the current scope and should be available every time the new showPopup is called (if I'm wrong about this, someone please correct me).
Let me know if this works out for you.
The HtmlObject provides all the necessary functionality to register managed event handlers for script and DOM events, but what if the class you need to listen to doesn't exist as a DOM element, but a scripting variable (referenced via ScriptObject) instead?
A javascript object doesn't support the concept of attached events. However it may support the concept of a property holding a reference to function that if assigned will be called at a certain point.
I take you have such an object?
If so you use the ScriptObject SetProperty method using the name of the property that should hold a reference to a function and a delegate to Managed method matches the signature that the Javascript object will call.
Caveat the following is untested at this point but should put you on the right path.
//Javascript in web page.
var myObj = new Thing();
function Thing()
{
this.doStuff = function()
{
if (this.onstuff) this.onstuff("Hello World");
}
}
// C# code in a Silverlight app.
class SomeClass
{
private ScriptObject myObject;
public SomeClass(ScriptObject theObject)
{
myObject = theObject;
myObject.SetProperty("onstuff", (Action<string>)onstuff);
}
function void onstuff(string message)
{
//Do something with message
}
}
As stated by AnthonyWJones, Silverlight can't attached to JavaScript events. The right thing to do in this situation is to do the following:
Enable scripting access in Silverlight:
Mark the class with the
ScriptableType attribute, or mark
the specific methods with
ScriptableMember
Call
HtmlPage.RegisterScriptableObject in
the constructor.
Once everything is set up in the Silverlight code, here's what you do in JavaScript:
Obtain a reference to the JavaScript
object and register an event handler
Use document.getElementById to get
the Silverlight control
Call .Content.. in the
JavaScript event handler. For
example,
silverlight.Content.Page.UpdateText(text).
So basically, all event handling is performed in JavaScript, but the JavaScript event handlers can be used to call functions in Silverlight.