I have a use-case for displaying paginated HTML tables and rather than generating the form using a script, I’m wondering if it’s feasible to pass in an array of objects and render those objects within tables in a series of pages using repeat groups.
It would be helpful if you have an example implementation I could look into.
Hmm, I do not think I have ever seen anything done that was quite like this. I have a couple things I want to test before giving a proper answer here, but I did have a few followup questions:
displaying paginated HTML tables
Did you want the HTML table to be paginated on the same form page, or can it be paginated by having different pages of the table on different form pages? (So you would use the form’s Next/Previous buttons to navigate between the different HTML table pages…)
pass in an array of objects
Where would this data be coming from? Is it static data that you know when designing the form, or will be coming in dynamically (via task/contact-summary/contact/etc)?
Got it. Okay, so there are several complexities at play here. The first one to address is perhaps the repeating through a data structure. This is pretty easy to do for a basic nodeset of string values:
type
name
label::en
calculation
repeat_count
calculate
my_array
“hello world"
calculate
my_array_length
count-selected(${my_array})
begin_repeat
my_repeat
${my_array_length}
calculate
array_entry
selected-at(${my_array}, position(…) - 1)
note
repeated_note
My Note: ${array_entry}
end_repeat
my_repeat
This will print “My Note: hello” on the first repeat page and “My Note: world” on the second.
I guess the other complexity will be around loading the data from your contact-summary fields so that you have a nodeset that you can loop through. I know you are already pretty familiar with loading data from the contact-summary, so maybe you already have that part figured out. Otherwise, could you give a basic idea (or even a simplified version) of the data structure you are loading? (I have seen examples of forms parsing some more complex data out of a string via the substring-after and substring-before functions…)
Then in separate pages I would display information for the specific CHW in table format. I’m looking into how to navigate the json structure to get the specific data elements to display within the form.
Okay, so bad news and good news. The bad news is that after some testing, the CHT’s pojo2xml logic does a very poor job of handling arrays. So assuming the length of the list of CHWs in the contact-summary is dynamic (and not always 2), we will have to get more creative than just dropping an array in the contact-summary context.
The good news is that if you normalize the CHW data into space-separated strings, it is still pretty easy to parse them out in the form logic. So, in your contact-summary logic you could have something like:
Of course, you will probably want to expand on the normalization logic to properly handle things like spaces in the name and non-existent values. Also, it is worth noting that the XPath references used for loading data from the contact-summary (e.g. instance(‘contact-summary’)/context/chw_referrals) should be able to support parsing out data from a list in the XML if it was properly formed. I think the root problem here is that our pojo2xml code is overly simplistic. But, in theory, that logic could probably be pretty easily updated to better support more complex data structures… (Though that could present some different challenges in the form logic since the repeat functions we are using operate against a “nodeset” and I am not sure how that maps when it comes to data we can load from the xml…)