Four Js Development Tools Forum

Discussions by product => Genero BDL => Topic started by: Sean H. on April 11, 2023, 12:48:15 pm



Title: Display An Array with Variable Number of Column
Post by: Sean H. on April 11, 2023, 12:48:15 pm
I was wondering if it is possible to get pointed in the right direction of handling a data structure like this with a Form Table.

Code
  1. data dynamic array of record
  2.   idno integer,
  3.   duration integer,
  4.   dates dynamic array of date
  5. end record
  6.  

The dates data column can have an unknown number of dates depending on the duration, like for example

Code
  1. [{
  2.     "idno":1,
  3.     "duration":3,
  4.     "dates":["2023/04/11","2023/04/12","2023/04/13"]
  5. },{
  6.     "idno":2,
  7.     "duration":2,
  8.     "dates":["2023/04/11","2023/04/12"]
  9. },{
  10.     "idno":3,
  11.     "duration":5,
  12.     "dates":["2023/04/11","2023/04/12","2023/04/13","2023/04/14","2023/04/15"]
  13. }]
  14.  

Ideally it would be great to show it in a Form Table like the below

Code
  1. | IDNO | DURATION | DATE 01     | DATE 02     | DATE 03     | DATE 04     | DATE 05     | ...
  2. | 0001 |     0003 | 2023/04/11  | 2023/04/12  | 2023/04/13  |             |             | ...
  3. | 0002 |     0002 | 2023/04/11  | 2023/04/12  |             |             |             | ...
  4. | 0003 |     0005 | 2023/04/11  | 2023/04/12  | 2023/04/13  | 2023/04/14  | 2023/04/15  | ...
  5.  


Title: Re: Display An Array with Variable Number of Column
Post by: Reuben B. on April 13, 2023, 02:15:22 am
Before I offer solutions, I'll just direct readers to https://4js.com/ask-reuben/ig-28/ and the beginning of this presentation https://4js.com/files/documents/wwdc21/plenary/A6_Table_vNext.pdf which help illustrate the architecture of Form Tables and give insight as to why you can do certain things and why you can't do certain things.

For the need described, I would ask the following questions -
what is the expected number of rows in the array
what is the expected number of entries in the dynamic array of date
with the proposed DATE 01, DATE02 columns, is there any expected functionality associated with those columns.  For instance if you clicked on DATE 03 column header, would you expect a sort on DATE 03 etc
is it possible for the number of date columns to increate during the display of the form

Based on those responses, then you might consider

1. Turn the array of dates into a string that contains a list of dates

Code
  1. data dynamic array of record
  2.  idno integer,
  3.  duration integer,
  4.  date_list string
  5. end record

Code
  1. | IDNO | DURATION | DATES
  2. | 0001 |     0003 | 2023/04/11, 2023/04/12,  2023/04/13
  3. | 0002 |     0002 | 2023/04/11, 2023/04/12
  4. | 0003 |     0005 | 2023/04/11, 2023/04/12, 2023/04/13, 2023/04/14, 2023/04/15

2. Display a count of the dates in a BUTTONEDIT field, and make the list of dates available in a popup

Code
  1. data dynamic array of record
  2.  idno integer,
  3.  duration integer,
  4.  date_count integer
  5. end record

Code
  1. | IDNO | DURATION | DATES
  2. | 0001 |     0003 | 3 ^
  3. | 0002 |     0002 | 2 ^
  4. | 0003 |     0005 | 5 ^

3. A solution you might have considered already is to hardcode the maximum number date columns, and hide the date columns that aren't used
e.g. hard coded maximum 20 dates.
Code
  1. data dynamic array of record
  2.  idno integer,
  3.  duration integer,
  4.  date01 date,
  5.  date02 date,
  6. ...
  7.   date20 date
  8. end record


4. If the number of rows or dates is not excessive, you could consider using a WebComponent to display the data as you'd like https://github.com/FourjsGenero/wc_2darray.  I make the disclaimer for number of rows not being excessive because if you are getting into the hundreds and thousands then you start needing to think of ways to not send every row to the front-end

5. Dynamic dialogs is also an option and will give you a UI that is closest to what you want.  You will need to parse the data beforehand to determine the maximum number of columns and hence determine your fields array http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_ClassDialog_dd_field_definition.html which would be something like ...

Code
  1. LET max_date_count = 0
  2. FOR i = 1 TO data.getLength()
  3.   IF data[i].dates.getLength() > max_date_count THEN
  4.       LET max_date_count = data[i].dates.getLength()
  5.   END IF
  6. END FOR
  7.  
  8. LET fields[1].name = "idno"
  9. LET fields[1].type = "INTEGER"
  10.  
  11. LET fields[2].name = "duration"
  12. LET fields[2].type = "INTEGER"
  13.  
  14. LET max_date_count =
  15. FOR i = 1 TO max_date_count
  16.   LET fields[i+2].name = "date", i USING "&&"
  17.   LET fields[i+2].type = "DATE"
  18. END FOR
  19. ...
  20. LET d = ui.Dialog.createDisplayArrayTo(fields, "scr")
  21.  

In creating your form dynamically http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_dynamic_dialogs_forms.html then you would be creating a form with max_date_count date columns

In setting the array values http://4js.com/online_documentation/fjs-fgl-manual-html/#fgl-topics/c_fgl_dynamic_dialogs_fields.html, you'd have two loops

Code
  1. FOR i = 1 TO data.getLength()
  2.    CALL d.setCurrentRow("scr", i)
  3.    CALL d.setFieldValue( "idno", data[i].idno)
  4.    CALL d,setFieldValue("duration", data[i].duration)
  5.    FOR j = 1 TO data[i].dates.getLength()
  6.        CALL d.setFieldValue(SFMT("date%1", j USING "&&"), data[i].dates[j])
  7.    END FOR
  8. END FOR

The downside with this approach is that you need to consider what happens if a date is added during the lifetime of the dialog, if this exceeds the maximum then you need to exit and reinstantiate the dialog.  If the list is static then not an issue.

Personally I'd favour approach 1 or 2 or a combination thereof e.g. BUTTONEDIT that displays a STRING that if 1-n dates lists them, if more than n dates displays a string "X dates from MIN to MAX" and the user clicks the BUTTONEDIT to see them

Code
  1. | IDNO | DURATION | DATES
  2. | 0001 |     0003 | 2023/04/11, 2023/04/12,  2023/04/13   ^
  3. | 0002 |     0002 | 2023/04/11, 2023/04/12                 ^
  4. | 0003 |     0005 | 5 dates from 2023/04/11 to 2023/04/15 ^

Hope this helps,

Reuben