I attempt to call a javascript method from another javascript method from java method
here is my code:
public void print(){
Excec();
}
native String flipName(String tst) /*-{
// ...implemented with JavaScript
alert(tst);
}-*/;
native String Excec() /*-{
alert("exe");
flipName("1");
alert("exe1");
}-*/;
when i run the application it show me an error :
Excec()([]): flipName is not defined
com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:249)
com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:136)
com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:576)
This must be done in about the same way as calling a Java method from within a JSNI method.
You must specify the fully qualified name of the method you wish to call, and you also have to specify the type of the argument.
More information can be found here : http://www.gwtproject.org/doc/latest/DevGuideCodingBasicsJSNI.html
In practice this will work (replace be.knarf.gwt.client.Example with the correct package name and class name of your class) :
private native void flipName(String tst)
/*-{
alert(tst);
}-*/;
private native void excec()
/*-{
alert("exe");
this.#be.knarf.gwt.client.Example::flipName(Ljava/lang/String;)("hi");
alert("exe1");
}-*/;
Related
I have created an android WebView, and injected javascript interface using addJavascriptInterface(mObject, "jsinterface"). It works fine until I create an object with same name (jsinterface) in JavaScript using the new operator.
My Java Code:
WebView mWebView = findViewById(R.id.myWebView);
mWebView.getSettings().setJavaScriptEnabled(true);
mWebView.setWebChromeClient(new MyWebChromeClient((Activity)mContext));
mWebView.addJavascriptInterface(new testClass(), "jsinterface");
mWebView.loadUrl("UrlToLoad");
testClass.java
public class testClass{
public testClass() {
}
#JavascriptInterface
public String testNativeMethod() {
return "Java method called!!";
}
}
My Java Script Code
test.js
function test(msg){
this.message = msg;
this.testJSMethod = function(){
return this.message;
}
}
alert(jsinterface.testNativeMethod()); // prints Java method called!!
jsinterface= new test("JS method called...");
alert(jsinterface.testJSMethod()); // prints JS method called...
alert(jsinterface.testNativeMethod()); // errors "NPMethod called on non- NPObject"
Problem:
Is this possible for a javascript object to have access to both , i.e javascript methods and native JAVA methods(exposed to it via javascriptinterface) ? Is there any possibility of setting any property to webview OR executing any JS script to get this done?
Think about document in javascript. When you are in a web browser, this is a global object that you have access to at any point. If you make your own new var called document, you are going to have problems accessing the global document.
When you execute this line:
mWebView.addJavascriptInterface(new testClass(), "jsinterface");
you are adding a global object called jsinterface. This is the same situation as document. If you create a var with the same name, it will overwrite the existing global reference.
Once you add a javascript interface to the WebView, you don't need to create a new reference to the interface. addJavascriptInterface has already done that for you.
TRY
You may try to make another object, which will retranslate calls to javascript interface.Implement onPageStarted method in WebViewClient , and inject javascript in onPageStarted method, in the following way.
mWebView.setWebViewClient(new WebViewClient() {
#Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
view.loadUrl(url);
return true;
}
#Override
public void onPageStarted (WebView view, String url, Bitmap favicon){
String jsScript= "javascript:var functions_array = ['testNativeMethod'];";
jsScript+="var jsinterface = {};"
jsScript+="functions_array.map(function(id){"
jsScript+="jsinterface[id]= function() {"
jsScript+="try{return temp_obj[id].apply(temp_obj, arguments);}"
jsScript+="catch(e) { console.log('ERROR: ' + e + ', method ' + id);"
jsScript+="return false;}}})"
view.loadUrl(jsScript);
}
});
Hope this helps :-)
I am working on a project using GWT and d3. i have used d3 in javascript files. Let me explain a bit more . i have a class name AstForm in GWT. in this class i have a function which i have called in my javascript file using following code.it the code works fine for me.
public native void PrepareFunctionsForJS() /*-{
$wnd.ExtractOFFNetWork = this.#org.valcri.asstsrchui.client.AstForm::ExtractOFFNetWork(*);
}-*/;
public void ExtractOFFNetWork(JsArrayMixed args)
{
Window.alert("thisCurrent row and Column is " +
args.getString(0) + " " + args.getString(1)+"OffenderNetwork?");
}
void testfunction ()
{
Window.alert("testfunction)
}
in java script i have used the following code
window.ExtractOFFNetWork(["GWT","JS"]);
my code works fine. i can call the ExtractOFFNetWork in javascript file. however the problem is in the ExtractOFFNetWork function when i call testfunction which is also the member function of the ASTFORM class the programe error saying testfunction is not a function. however when i changed testfunction as static than i can access this function within ExtractOFFNetWork. alternatievly i can also use the testfunction inside ExtractOFFNetWork by creating a separate object of ASTForm as
AstForm my =new AstForm();
my.testfunction();
however i do not want to use either static or separate ASTform object to access member function of ASTForm. i also used this.testfunction() within ExtractOFFNetWork but it also does not work. i would appreciate if any body can help to solve my problem i have spend full day without any success :)
already tried this when calling your PrepareFunctionsForJS(btw by java naming conventions method names start with lowercase letter..)
//assuming that you are calling the prepare function from inside the AstForm
public class AstForm() {
//...
PrepareFunctionsForJS(this);
}
public native void PrepareFunctionsForJS(AstForm instance) /*-{
$wnd.ExtractOFFNetWork = instance.#org.valcri.asstsrchui.client.AstForm::ExtractOFFNetWork(*);
}-*/;
js code like this:
function a(){return "hello";}
in android webview activity, how to call js function a() get the return value "hello" ?
webview.addJavaInterface? webview.loadUrl()? i can`t get it.
please tell me how to solve the problem.
My advice would be:
1- Define a Javascript interface
A plain Java class with some methods and attributes, use annotation to expose the method you desire to the webview JS scope
public class MyInterface {
private WebView webView;
//pass the reference to the webview in your constructor
public JavascriptCallback(WebView webView) {
this.webView = webView;
}
//expose this method to the JS scope using annotation
#JavascriptInterface
void sumNumbers(final String num1, final String num2, final String JScallbackFn) {
this.javascriptCallback(JScallbackFn, num1 + num2);
}
//run the callback into the JS scope
void javascriptCallback(final String callback, final String result) {
webView.post(new Runnable() {
#Override
public void run() { webView.load("javascript:"+callback+"("+result+")", null);
}
});
}
2- Inject the JavaScript interface in your webview
webview.addJavascriptInterface(new MyInterface(this.getActivity(), webview), "MyInterface");
3- Invoke the JS method (from within the webview)
MyInterface.sumNumbers(12, 34, showResult);
function showResult(res) {
document.getElementById('myDiv').innerHTML(res);
}
For more extensive explanation about how webviews works on Android check the official documentation http://developer.android.com/guide/webapps/webview.html
I am calling an static web method, the method is written in an aspx.cs file having two public classes:
public class Employee
{
public string EmployeeNumber;
public string FullName;
public string LoginName;
public string EmailID;
public string Phone;
}
public partial class CustomWebMethods : LayoutsPageBase
{
[WebMethod]
public static List<Employee> GetEmployeeDetails(string employeeLoginName)
{
List<Employee> lstEmployeeDetail = new List<Employee>();
//do something
return lstEmployeeDetail;
}
}
If I keep the public class employee in the same page then ajax call is working fine.
But if I move the employee to another class library project and add reference of that project, ajax call is not working. Why?
Javascript method not able to call the web method at all.
This is because of WebMethod attribute internal works. When you mark some method with this attribute, it will be available through PageName.aspx/MethodName url.
Then, after moving this method to outer library, you moving it from the page methods too, and after that it's not available.
So, if you want to refactor your code, you have to add the WebService to your project, from that class you can call methods from other library.
You can also create a javascript proxy on your client like this:
<asp:ServiceReference InlineScript="true" Path="~/CustomersService.asmx"/>
Or use the ScriptManager for it, like this:
<asp:ScriptManager ID="sm" runat="server" EnablePageMethods="true" />
After that you can use this proxy instead of ajax call.
<script type="text/javascript">
function Add()
{
var x = $get("txtX").value;
var y = $get("txtY").value;
PageMethods.Add(x, y, OnWSAdd);
}
function OnWSAdd(result)
{
$get("spanAddResult").innerHTML += result;
}
</script>
Old, but great article about Understanding ASP.NET AJAX Web Services.
I'm evaluating the JavaScript/Silverlight interop capabilities and have been able to create a Silverlight instance using JavaScript and call methods on it. However, I now need a way of passing a JavaScript callback function to Silverlight.
Simply passing a JavaScript function to a Silverlight method expecting an Action doesn't work although the error suggest that it's intended to. What am I missing? The exception details:
Microsoft JScript runtime error: System.ArgumentException: Cannot bind to the target method because its signature or security transparency is not compatible with that of the delegate type.
at System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo method, Boolean throwOnBindFailure)
at System.Windows.Hosting.ScriptingInterface.GetDelegateForScriptObject(Type eventHandlerType, ScriptObject obj)
at System.Windows.Browser.ScriptObject.ConvertTo(Type targetType, Boolean allowSerialization)
at System.Windows.Hosting.ScriptingInterface.GetScriptParamValueForType(ScriptParam scriptParam, Type desiredType)
at System.Windows.Hosting.ScriptingInterface.ConvertFromScriptParams(ParameterInfo[] parameters, ScriptParam[] args)
at System.Windows.Browser.ManagedObjectInfo.ScriptMethod.Invoke(ManagedObject obj, InvokeType invokeType, ScriptParam[] args)
at System.Windows.Browser.ManagedObjectInfo.Invoke(ManagedObject obj, InvokeType invokeType, String memberName, ScriptParam[] args)
at System.Windows.Hosting.ManagedHost.InvokeScriptableMember(IntPtr pHandle, Int32 nMemberID, Int32 nInvokeType, Int32 nArgCount, ScriptParam[] pArgs, ScriptParam& pResult, ExceptionInfo& pExcepInfo)
Without seeing your code I cannot say what you are doing wrong but I can describe what has worked for me in the past.
On the Silverlight side you need to register a class as a scriptable object. Then create a method that is marked as a ScriptableMember and takes a string that will be your passed in JavaScript method. I also added a method called InvokeCallback which will invoke the passed in javascript callback.
[ScriptableType]
public partial class Page : UserControl
{
private string jsCallback;
public Page()
{
InitializeComponent();
HtmlPage.RegisterScriptableObject("silverlightInterop", this);
}
[ScriptableMember]
public void RegisterCallback(string callback)
{
jsCallback = callback;
}
public boid InvokeCallback(string arg)
{
if(!string.IsNullOrEmpty(jsCallback))
{
System.Windows.Browser.HtmlPage.Window.Invoke(jsCallback, arg);
}
}
}
On the JavaScript side you can call the RegisterCallback method that you defined in Silverlight by grabbing the silverlight object on the page and calling the method off of the name "silverlightInterop" which we registered as the name of our scriptable object.
function jsCallback(someArg) {
alert(someArg);
}
var silverLightControl = document.getElementById("silverlightControl");
silverLightControl.content.silverlightInterop.RegisterCallback("jsCallback");
I hope this helps. I also have some sample code the demonstrates this which I wrote a while ago here
There is a simpler way to pass Javascript function to Silverlight. All values from javascript can be represented by the ScriptObject type, this includes a function. Its for this reason that the ScriptObject has a InvokeSelf method.
You can create a property as simple as:-
[ScriptableMember]
public ScriptObject Callback { get; set; }
Now lets say in Javascript we have this function:-
function sayHello(name)
{
alert("Hello " + name);
}
We can assign this to the property (assume the RegisterScriptableObject("Page", this) has been done) with this JS:-
document.getElementById("mySL").Content.Page.Callback = sayHello;
Now in Silverlight code we can invoke this Callback with:-
Callback.InvokeSelf("Freed");
Apparently, this does work if the using a delegate type of EventHandler (or EventHandler<>), but not for other delegate types.
My Code:
<!-- language: JavaScript -->
function sendText() {
return "Hi from Javascript!";
}
<!-- language: C# -->
string obj = HtmlPage.Window.Invoke("sendText", null) as string;
txtReturnData.Text = obj;
<!-- language: VB.Net -->
Dim obj As String = TryCast(HtmlPage.Window.Invoke("sendText", Nothing), String)
txtReturnData.Text = obj