enketo / enketo

Enketo web forms monorepo
Apache License 2.0
9 stars 13 forks source link

Separation of logic and presentation to allow for better integration of enketo-core #1314

Open hansmbakker opened 2 weeks ago

hansmbakker commented 2 weeks ago

Is your feature request related to a problem? Please describe. We would like to embed an enketo-core-based survey in a webview in a mobile app. To build a good integration, we would like to build some parts on the native side. Examples are the previous/next buttons and the table of contents.

Currently, the enketo-core logic is very tightly coupled to the presentation. It makes assumptions about page elements (that developers need to add) like buttons in

https://github.com/enketo/enketo/blob/bfa9a69bf2fe885950e7e75d1600786d72ebfdb7/packages/enketo-core/src/js/page.js#L83-L88

and directly performs modifications on those like in https://github.com/enketo/enketo/blob/bfa9a69bf2fe885950e7e75d1600786d72ebfdb7/packages/enketo-core/src/js/page.js#L496-L502

This limits developers in how they build e.g. their navigation buttons, or presentation of the table of contents.

Describe the solution you'd like Dot on the horizon: enketo-core really focusing on being a core package, emitting events and providing methods to integrate with.

For example

Describe alternatives you've considered Using use the html elements that enketo-core expects, make them invisible, and add event listeners to them and perform automated clicks on them

hansmbakker commented 2 weeks ago

Cc @Przemko92 @ppluijten

hansmbakker commented 2 weeks ago

A first step could be to add events like an navigation state changed event in https://github.com/enketo/enketo/blob/bfa9a69bf2fe885950e7e75d1600786d72ebfdb7/packages/enketo-core/src/js/page.js#L496-L502

to the existing code - even if the tight coupling to the assumed HTML buttons would stay, it would allow external code to respond to the state change in enketo.

lognaturel commented 5 days ago

I believe Medic mobile takes control of UI components in a similar way so maybe @jkuester would be willing to chime in with their chosen approach. It's possible that they fork Enketo and add these kinds of events.

We (the ODK team) have decided to step down as primary maintainers of Enketo so will not be considering additions like the one you propose currently. We are seeking new maintainers.

We have started work on a new ODK XForms platform that will be client-side only and provide more separate layers. It has a ways to go before it is production-ready but you may find it interesting.

lognaturel commented 4 days ago

See also https://github.com/enketo/enketo-express/pull/454, https://github.com/enketo/enketo/issues/938

jkuester commented 2 days ago

For what it is worth, in https://github.com/medic/cht-core we are including enketo-core inside our Angular webapp. This is done without forking enketo-core or any kind of major code changes (we patch a few files, but that is to maintain some backwards compatibility of our own janky behavior and not due to integration issues). That being said, the integration is not the most clean and I agree that a more module structure (maybe based on web components?) would make maintenance easier.

Here is an example from our webapp code where we are basically rolling our own buttons by tapping into the aforementioned private _next function....

TLDR is that it can be done. It is not the most pretty, but it has served us well for a long time! Happy to answer any more specific questions you might have regarding our integration.