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.
thanks for your feedback.
I agree with you that the current view for displaying question types is far from being ideal (it was the safer and quicker option at that time and has proved to work well), so any suggestion for improvement is welcomed.
Your solution sounds reasonable the only issue I see is that Web Services do not support dynamic structures when returning data (it has to be a pre-defined data structure) so we will be needing a superstructure able to return any question type data (question and answers required data).
Just checking all the different question types db/install.xml files you can image that it won't be easy to created a pre-defined structured supporting all the required structured data for any question type.
I feel there are several approaches:
- Use just one field for the questionstructure where will be storing the question information in JSON format. So the app can decode it.
- Create a standarised structure able to support the most common data and any kind of extra data
- Return the questions already rendered in an ionic compatible way.
Thanks Juan. I agree that what was done so far was bat seemed like the best option at the time, and it did allow the app let students attempt quizzes in the app as of a few versions ago. This was a really important milestone to reach, and I don't want to underplay the amount of work that took.
However, I disagree that what was done "has proved to work well" in anything but the simplest cases. For example, here is a Cloze question in the app:
It is using HTML radio buttons, not app-native ones.
For background, I am working on making the STACK question type work in the app (clearly a sensible choice of simple question type for me to start learning with ). Last night I got I reached the conclusion "this is probably impossible". Then this morning, I thought "Acutally it can't be impossible, they must have dealt with this issue when they implemented Cloze question type in the app". Now I have time to investigate, I see that actually, you could not make it work the way one would want it to work either, so at least I am not missing anything simple.
You make a very good point about web service return values needing to be fully defined. I had forgotten that, and that means that my suggestion clearly requires more work.
There is no "standarised structure able to support the most common data" for differnt question types. That is why we have different question types.
So, I think your third suggestion "Return the questions already rendered in an ionic compatible way" sounds like the most promising option. (Returning a JSON is clearly just cheating to get around the rule about having to define the structure.)
However, clearly my suggestion needs more work, and I will continue to think about it. I will probably get back to you when I have a better worked out idea. Thanks again for your feedback.
I think of the way question types work on mobile as 'screen scraping' the web output. I know that is not an exact analogy, but it give s a feeling of something that will work, but you might have done it differently if you were starting from scratch. When I did the first version of Gapfill for mobile it was nice that the changes I had to make to the web output were trivial and reflected things I should have probably done anyway.