Integrating third-party libraries with GWT using JSNI

I am currently working on integrating Opentip into a GWT project. Since some of my widgets are loaded from Java rather than HTML, it seems like I will need to utilize JSNI in order to properly bind those tooltips. Here is the progress I have made so far:

  1. Inserted the necessary JS/CSS declarations before GWT's nocache.js in my HTML file. (I also attempted duplicating the JS loading using ScriptInjector, but ultimately removed it as it was redundant.
  2. Created a JSNI method to initialize the tooltips:

    private native void initControlTooltips() /*-{
        var headerText = "Tooltip text";
        new $wnd.Opentip($("#tooltipTrigger"), headerText);
        // more tooltips...
    }-*/
    

I have experimented with different variations of the above method, but from what I've researched, this appears to be the correct approach (Slide 20 here, though direct linking to the slide isn't possible). Unfortunately, I have not had success yet, and my latest attempt, which seems most accurate to me, has actually caused the remaining parts of my GWT module to stop loading (following the tooltip instantiation call), seemingly due to a syntax error somewhere, though nothing is being reported in the console. Any insights into what I may be doing wrong would be greatly appreciated. As I am relatively new to both GWT and JS, I'm hoping it's just a novice mistake.

One thing I have not tried is creating an Overlay object, partly because I am unsure how to correctly wrap a JS constructor based on the documentation. If that turns out to be the solution, any guidance on how to go about it would be helpful. The constructor I would be using (as per the Opentip documentation) is:

new Opentip("#my-trigger-element", "Optional content", "Optional title", { ...options... });

Thank you for any assistance; while this doesn't appear to be an overly challenging issue, my lack of experience has hindered my progress thus far.

Update

After numerous hours of frustration and tweaking parameters, I have managed to resolve this on my own. So please do not waste your time attempting to help me troubleshoot. I will provide an update later today when I have a moment free.

Answer №1

After setting up your web.gwt.xml, module, and EntryPoint, you may be looking to integrate external JavaScript with your GWT widgets solely without direct access from the HTML. If you haven't set up these components yet, this answer might not apply to you. It's always helpful to refer to The documentation as a starting point for GWT development. In this example, we will use Opentip, but the method discussed should be adaptable to other libraries as well.

  1. In your web.gwt.xml file, ensure that you include the source of your desired library within the module entry where you intend to utilize it. By doing so, you may avoid the necessity of declaring it in the static HTML of your page unless required.

    <script src="../js/opentip/opentip-jquery.min.js"/>
    

    (Take note of the relative path ../ which should align with the location of your GWT-generated HTML on the server and needs to be accessible by your web server.)

  2. Create a JSNI method in your module class to initialize the library by calling its constructor in the following manner:

    private native void initTooltip() /*-{
        new $wnd.Opentip($doc.getElementById("tooltipTrigger"), "Tooltip text");
    }-*/;
    

    (Observe the usage of $wnd to reference the top-level window and $doc to reference the document. Prefixing with $wnd. allows access to any globally declared variables from external JS files.)

No complex Overlay types or ScriptInjector calls are necessary. During my implementation, I encountered an issue where getElementById() returned null due to calling the JSNI method before the relevant object was added to the DOM within onModuleLoad().

This experience highlighted a simple beginner's mistake. Hopefully, this explanation can assist others in synthesizing various solutions into one viable approach for addressing similar challenges.

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

Locate the product of n numerals within a specified interval

Is there a way to determine the number of multiples for N unique numbers (provided as an array input) within the range of 1 to K, where 1 < K < 10⁸ and 3 ≤ N < 25? function findNumberOfMultiples(inputAr ...

Issue with filtering of values returned by functions

I've been working with Angular's currency filter and I've run into an issue. It doesn't seem to be filtering the data that is returned from a function. I have a feeling that I might be missing something, perhaps it has to do with how th ...

After downloading the latest version of NodeJS, why am I seeing this error when trying to create a new React app using npx?

After updating to a newer version of NodeJS, I attempted to create a new React app using the command npx create-react-app my-app. However, I encountered the following error message: Try the new cross-platform PowerShell https://aka.ms/pscore6 PS E:\A ...

Next.js Pre-rendering Issue: Error encountered when trying to access properties of a null object

Using Next.js for a React application (full code available here.) Encountering an unusual error while running next build, showing errors related to prerendering on five pages: spenc@WhiteBoxu:~/workout-tracker$ next build info - Loaded env from /home/spe ...

Is it necessary for me to develop a component to display my Navigation Menu?

After designing a Navigation menu component for desktop mode, I also created a separate side drawer component to handle variations in screen size. However, a friend of mine advised that a side drawer menu component may not be necessary. According to them ...

Using React Bootstrap, you can ensure that only a single collapse opens at a time when rendering it with a map function. This allows you to display

When a user clicks on the "View Tasks" button, I want to display the relevant tasks specific to that user. However, currently all React Bootstrap Collapse Components open up and show tasks for every user instead of just one. This issue arises because the o ...

JavaScript - Populating Dropdown Menu with Fresh Information

I'm attempting to populate a combobox (input) with data fetched via AJAX. The goal is to display every city associated with a selected state, chosen from another select control (the state control). My Attempt: I've implemented the "change" even ...

Implementing jQuery/JavaScript to efficiently iterate through JSON data

I have implemented a form that allows users to select an item from a multi-select dropdown (A). If the desired item is not listed, users can manually add it using another text input box (B). Once added, an AJAX call saves the item to the database. After su ...

Using npm to install packages with multiple package.json files

My current project includes a submodule with another submodule, each having their own package.json file. This is how I set up my project: |root ----|node_modules ----|package.json ----|someFolder ----|submodule_1 -------- |package.json -------- |someFold ...

There was a mistake: _v.context.$implicit.toggle cannot be used as a function

Exploring a basic recursive Treeview feature in angular4 with the code provided below. However, encountering an error when trying to expand the child view using toggle(). Encountering this exception error: ERROR TypeError: _v.context.$implicit.toggle i ...

Dealing with performance issues in VueJS and Vuetify's data-table component, especially when trying to implement

In my VueJS and Vuetify project, I encountered an issue. I am trying to create a table with expandable rows for displaying orders and their associated products. The table needs to show at least 100 rows of orders on one page. To achieve this, I utilized th ...

Using the LIKE operator in MSSQL within a Node.js SQL query

Is there a way to fetch data even when the query value for "naziv" is not an exact match with the value in the table, but just similar? const sqlConfig = require("../config/ms.config") exports.data = async (req, res) => { const { sifar ...

Dual-wedge shaped loops in a for loop structure

Struggling with creating a dual-wedge figure using for loops for an assignment. Can anyone lend a helping hand? Display of the desired outcome: ******* *** *** ** ** * * Below is my attempt at the code: int dual_wedge_length=9; int half_length = ...

Including an element to a React list

I am struggling to figure out how to add a new fruit to the existing list of fruits. Currently, when I submit, it just adds an empty string li to the list. Can someone help me with this issue? Here is my fruit list component: import AddFruit from '. ...

Exploring the depths of JSON: Unraveling the secrets of reading dynamic object data

Currently, I am receiving a JSON file from another app and my goal is to parse it in order to extract the data contained within. The JSON includes user-defined dynamic data with changing key/value pairs, which has left me feeling uncertain about how to eff ...

In JavaScript, the way variables are logged can vary depending on whether they are passed through an onclick function or not

I'm completely stumped on this issue and need some help unraveling it. I've been working with the following code: function setMarkup(data) { response += "<div class='column' style='float: right;'> ...

Is it possible to utilize the `key` prop in React for purposes other than lists?

Check out the sandbox example here: https://codesandbox.io/s/young-fog-cpjg15?file=/src/App.tsx In my React application, I have a table of items and a sidebar for editing selected items. The input fields are controlled components as per the documentation ...

UI changes are not appearing until after the synchronous ajax call

I have two JavaScript functions that are called one after the other, as shown below. updateUI(event); syncCall(); function updateUI(event) { formSubmitBtn = $(event.target).find('[type=submit]:not(".disabled")'); formSubmitBtn.attr('di ...

Saving numerous files with Promises

There is a Node URL (created using Express) that enables users to download static images of addresses. The calling application sends a request to the /download URL with multiple addresses in JSON format. The download service then calls Google Maps to save ...

Inheritance of Mongoose methods across all Schemas using the Schema method

Currently, I am working on nodejs with Mongoose and have data in various collections with _id as a string manually written by the user. I am looking to refactor this process and automate the generation of _id. My aim is to create a separate JavaScript fil ...