When implementing question types in the mobile app, the approach adopted was to use exactly the same rendering code to render the question HTML that is then sent to the app is used when the quiz is attempted in a web browser.
If what we wanted was identical display of questions in the app and in the browser, this would be great, and would save plugin developers a lot of work.
Unfortunately, we don't want identical display. We want things in the web browser to look like thinkgs normally do in HTML, and we want things in the mobile app to look like native browser apps. For example, a multiple choice question:
So, regrettably, what we have ended up with is code like this in the app. That takes the HTML sent by the web service, parses it to extract the question stem and the choices, and then that is re-rendered client-side using an ionic template.
This is surely far from ideal. If what the mobile app acutally needs is structured data (the question stem, and the separate choices) the surely it would be far more robust and performant for the web service to send the the data that is needed, rather than to be parsing HTML in JAVA script.
There is then the quesion of whether this could be implemented in a backwards compatible way. I think yes:
(All the variable/method names in the following are horrible, and need to be improved, but hopefully they make my suggestion clear.)
- Change the web service to return, in addition to the existing ->html, a new field ->displayedquestionstructure.
- ->displayedquestionstructure is set by a new call ->render_for_web_service(...). There probably also needs to be a new boolean method ->supports_separate_render_for_web_service() - returns false be default in the base class.
- For efficiency without breaking backwards compatibility, add a new optional argument to that web services $nohtmlifdisplayedquestionstructure default false.
- Then, in the mobile app, we start calling the web service with $nohtmlifdisplayedquestionstructure = true, and if we get ->displayedquestionstructure in the data for a particual question, then we just use that directly, and we don't call the method like initMultichoiceComponent to parse the HTML. Instead we feed displayedquestionstructure directly to the template. If ->displayedquestionstructure is null, then we continue to parse ->html like at present. This means that all the question types that currently work keep working.