NOTE: This widget is not production ready (hence we're going with a lower version number) and should only be used when applicable. I haven't published this widget to the MarketPlace yet.
This is a work-in-progress rewrite of the Web View widget that is part of the Native Mobile Resources, published by Mendix R&D.
This may or may not be incorporated in the original widget eventually.
- Based on reavt-native-webview version 11.17.1
- Rewrote in a Functional component, not class.
- Removed OnLoad (useless, can be replaced by Navigation)
- Added an option to expose the webview to the page (Experimental, see below)
- Added more attributes for different Events (all JSON stringified):
- Error -> General errors in the webview.
- HTTP_Error -> Specific HTTP Errors.
- Navigation -> Triggered when a page is loading (
loading: true
) or loaded (loading: false
) - Message -> This is used in conjunction with
window.ReactNativeWebView.postMessage([string])
in the loaded page itself.
For every type of event mentioned above, the widget will stringify a JSON of the event and add this to the attribute. It will then trigger the action. The best way to handle this is by executing a Nanoflow.
- Domain Model
This is the domain model I use. The widget uses the Url attribute to view a certain page, the Navigation attribute is used in the widget to track navigation changes
- Nanoflow
On Navigation (see Events tab in the widget) is triggered, which contains a Javascript Action. This action will take the JSON string out of the Navigation attribute and convert this to a new WebViewEvent object. You can do anything with it afterwards.
- Javascript Action
The code (click to open) might be changed. I noted that the attribute names might not always correspond with the keys in the JSON
JS Action code
// This file was generated by Mendix Studio Pro.
//
// WARNING: Only the following code will be retained when actions are regenerated:
// - the import list
// - the code between BEGIN USER CODE and END USER CODE
// - the code between BEGIN EXTRA CODE and END EXTRA CODE
// Other code you write will be lost the next time you deploy the project.
import { Big } from "big.js";
// BEGIN EXTRA CODE
function createMxObject(entity) {
return new Promise((resolve, reject) => {
mx.data.create({
entity,
callback: resolve,
error: () => reject(new Error(`Could not create '${entity}' object`))
});
});
}
async function createParamObject(entity, data) {
const mxObject = await createMxObject(entity);
mxObject.getAttributes().forEach(attributeName => {
const value = data[attributeName.toLocaleLowerCase()];
if (value) {
mxObject.set(attributeName, value);
}
});
return mxObject;
}
// END EXTRA CODE
/**
* @param {string} jSON
* @param {string} entity
* @returns {Promise.<MxObject>}
*/
export async function Importer(jSON, entity) {
// BEGIN USER CODE
if (!jSON) {
return createMxObject(entity);
}
try {
const obj = JSON.parse(jSON);
if (obj) {
return createParamObject(entity, obj);
}
} catch (e) {
console.warn(e);
}
return createMxObject(entity);
// END USER CODE
}
Basically, the JS Action will create a new object, go over all the attributes and fill these with the values found in the JSON.
You might ask... "Why?". Well, I want the widget to not alter any info (in onNavigation, onMessage, onError etc) and give the Mendix Developer the possibility to do whatever they want with it. That's why I create separate entities that can be filled, so you can then properly process it in your Nanoflows
Yes, the JS Action is not the cleanest solution, but unfortunately we can't use proper JSON structures and import mappings in Native.
NOTE: This is HIGHLY experimental and I don't know if this works in production. In my tests it worked in the
Make it Native
app, but haven't tested it in production. Don't use it if you don't need to!
There is an option in Advanced that can be used to expose your widget to the window
object.
- Let's say your widget name is
webview_Revamped
(see widget tabCommon
) - Switch on
Expose to window
inAdvanced
- Now you could potentially access the webview from a Javascript Action using
window[widgetName]
(wherewidgetName
is"webview_Revamped"
in this case)
Why?
/**
* @param {string} webViewName
* @returns {Promise.<void>}
*/
export async function JS_WebView_Go_Forward(webViewName) {
// BEGIN USER CODE
const view = window[webViewName];
if (view && view.goForward) {
view.goForward();
}
// END USER CODE
}
You can fire a few events on the webview component. There are interesting things you could do.
See react-native-webview methods
This can potentially be used to for example stop the webview from loading, inject custom javascript in the page itself etc.
See official Mendix Docs, the class name should be:
TBD, figuring this one out
- Install NPM package dependencies by using:
npm install
. If you use NPM v7.x.x, which can be checked by executingnpm -v
, execute:npm install --legacy-peer-deps
. - Run
npm start
to watch for code changes. On every change:- the widget will be bundled;
- the bundle will be included in a
dist
folder in the root directory of the project; - the bundle will be included in the
deployment
andwidgets
folder of the Mendix test project.
Apache-2