How can I utilize JavaScript to call a Delphi function in TWebBrowser on Delphi XE6 for all platforms, such as iOS and Android?

My goal is to develop an application using Delphi XE6 for Android and iOS that utilizes a TWebBrowser to display Google Maps. I need the ability to communicate between Delphi and JavaScript, allowing me to interact with markers on the map based on user input.

While I have come across this helpful article that demonstrates how to execute JavaScript from Delphi code, I am still unsure of how to call a Delphi procedure from JavaScript within the TWebBrowser component.

For instance, let's say I have a Delphi procedure like this:

procedure JSFeedback(aParm1, aParm2, aParm3, aParm4: string);

I want to be able to use JavaScript in the TWebBrowser to call this procedure and pass it four parameters. While I've found some resources for calling Delphi procedures from JavaScript in Windows applications, I'm having trouble finding solutions that work seamlessly on Android (I haven't tested on iOS yet).

Answer №1

To implement this functionality, one can utilize the addJavascriptInterface function within the Android WebView. References and examples of this method can be found here, here, and here.

It is important to note that the Firemonkey TWebBrowser does not inherently support this feature.

A solution could involve implementing a custom WebView wrapper control in DPF Android, which is illustrated here.

For IOS development using TWebBrowser, custom web browser controls are available on sourceforge and here.

An alternative approach is utilizing the OnShouldStartLoadWithRequest event of TWebBrowser. This can be achieved by executing JavaScript within the event like:

<script language=”javascript” type=”text/javascript”>
window.location.href=”#param1&param2&param3&param4”;
</script>

or

<script language=”javascript”>
window.navigate(”javascript:thisisatest();”);
</script>

By examining the URL property of OnShouldStartLoadWithRequest for specific patterns or values, desired actions can be triggered without changing the existing page's URL.

Answer №2

Utilizing JavaScript to interact with HTTP servers, such as through jQuery, is a common practice. By making your Delphi code accessible via HTTP - either locally or on the web - you can enable your JavaScript code to call Delphi functions by sending an HTTP request and receiving data from Delphi functions in return.

WebSockets offer another option. This extension of HTTP allows for asynchronous communication, enabling the Delphi server to push data to the script without waiting for a request first (referred to as server push or Comet).

This approach provides a standards-based solution that is widely used and not tied to a specific web client. The Indy library, which is free and open source, can be utilized on all supported platforms to create HTTP servers that can operate independently or be integrated into your application.

Exploring other protocols, such as STOMP, may also prove valuable for facilitating communication between JavaScript and servers.

For a specific function, an HTTP call utilizing a GET request with parameters could look like this:

http://localhost/JSFeekback?par1=val1&par2=val2&par3=val3&par4=val4

Answer №3

By using JavaScript, you can change the <code>TWebBrowser.URL
property:

window.location.href="#param1&param2&param3&param4";

You can then either run a timer to monitor the changes in TWebBrowser.URL, extract the parameters, call your JSFeedback function, and reset the URL. Alternatively, you can achieve the same without a timer by following this code:

wb1.EvaluateJavaScript("window.location.href=\"#param1&param2&param3&param4\";");
getParams(wb1.URL);
JSFeedback(p1, p2, p3, p4);

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Utilizing JavaScript for Formatting and Comparing Dates

Here, I would like to compare the current date with a user-inputted date. <script type="text/javascript"> $(document).ready(function(){ $("#date").change(function(){ var realDate = new Date(); var startDate = new ...

What is the process to gain entry to a Vue3 instance from another location in order to execute a specific function

Is there a way to access a Vue 3 instance when I am not aware of the variable name that holds this instance? I need to be able to execute a function from a specific component. Upon typing $0.__vue_app__ in the console (Chrome Developer Tools), I can see t ...

Tips on sending multiple values to AngularJS Directive

Currently, I am in the process of creating a simple AngularJS directive. As I am still very new to AngularJS, I would appreciate it if the answers provided could be simplified! The directive I am working on is essentially a combobox. For those unfamiliar ...

The property of Three.js Quaternion is immutable and cannot be reassigned

I'm attempting to develop a class (using three.js) that utilizes an array containing vector names to compare with an array containing a set of 3D vectors in order to generate a mesh of a flat face. However, I am encountering an error. Uncaught TypeEr ...

Transferring information from JavaScript to PHP in a CakePHP framework

Hello there! I'm facing an issue with a select element that has multiple options. When an onChange event is triggered, I can successfully retrieve the selected option. However, now I need to send that option text to PHP either through pageload or ajax ...

Tips for modifying the settings of a current google chart within a wrapper

Is there a way to update the options of an existing Google chart? For instance, if I want to apply these options to a chart with just a click of a button: var newOptions = { width: 400, height: 240, title: 'Preferred Pizza Toppings', col ...

Creating a flexible image layout within a container with relative positioning

I attempted to create a basic slideshow with images sliding from right to left as an animation: let slides = document.querySelectorAll('.img-container'); let l = slides.length; let i = 0; setInterval(function(){ i = (i + 1) % l; if(i == 0){ f ...

Tips for confirming a date format within an Angular application

Recently, I've been diving into the world of Angular Validations to ensure pattern matching and field requirements are met in my projects. Despite finding numerous resources online on how to implement this feature, I've encountered some challenge ...

Tips on concealing an image within a second

Can anyone assist me with hiding an image right after a flip animation ends, within one second? ...

Broadcasting TypeScript Data Structures via Socket.IO

In my Typescript code, I have created a basic User class as shown below: export class User { constructor(public id: string); } When I emit a message from my socket.io server, I include an instance of the User class like this: var user = new User(&ap ...

Efficiently loading components in Angular using browserify with lazy loading

As I work on developing the architecture of a complex application with Angular, I have started with the angular-seed project which seems to be a solid starting point. However, one issue that concerns me is how Angular apps tend to load everything upfront b ...

Creating a three-dimensional shape using a transparent image in Three.js

Hey there! I'm currently working on creating a 3D model that features the upper and lower sides as transparent images, while the other sides are a solid color (yellow in this case). var texture = new THREE.TextureLoader().load( 'img.png' ); ...

What is the best way to restore an Angular 4 FormGroup to its initial state?

I have been delving into Angular4, specifically reactive forms. While experimenting with the Heroes demo, I encountered a hurdle. On this Plunker example, we are required to select a superhero and view their corresponding addresses. I added a reset button ...

Strange behavior of shadows within Three.js

I've been working on creating a mini solar system but encountered an interesting issue. I want all the planets to cast and receive shadows from each other, but it seems like the shadow casting depends on the order of instancing. Here is the code for t ...

What is the best way to add curves to a CGPath?

Take a look at the screenshot below: Notice how dragging the end of the word balloon's tail causes it to curve, as shown in the two different tails in the image. How is this effect achieved? My assumption is that you start with a CGPath and manipulat ...

Using asynchronous functions in a loop in Node.js

Although this question may have been asked before, I am struggling to understand how things work and that is why I am starting a new thread. con.query(sql,[req.params.quizId],(err,rows,fields)=>{ //rows contains questions if(err) throw err; ...

Displaying a portion of a React functional component once an asynchronous function call has been successfully executed

I am currently using material-ui within a React function component and have implemented its Autocomplete feature. I have customized it so that when the text in the input field changes, I expect the component to display new search results. callAPI("xyz") I ...

Retrieve the database value for the chosen name and then add that name to a different table

I am working on a dropdown feature that fetches categories from a database and displays the selected category price in a textfield. For example, when 'web development' is selected, the price ($12) will display in the textfield. Below is the cod ...

Identifying the presence of a property value within a collection of objects

I am trying to verify the existence of a 'member' object with a specific 'ID' in the 'members' array of an 'EntityGroup' container object. I'm having trouble understanding why the EntityGroup.idExists(id) method ...

Remove an item using a function embedded within it

I've been grappling with this issue for quite some time now and I'm unable to find a solution. My approach involves Vue(JS). What I'm attempting to achieve is to push notifications into an Object and then present them to the user. Each noti ...