Four Js Development Tools Forum

Discussions by product => Genero BDL => Topic started by: Sean Hadnum on April 11, 2023, 12:48:15 PM

Title: Display An Array with Variable Number of Column
Post by: Sean Hadnum 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 (genero) Select

data dynamic array of record
   idno integer,
   duration integer,
   dates dynamic array of date
end record


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

Code (genero) Select

[{
    "idno":1,
    "duration":3,
    "dates":["2023/04/11","2023/04/12","2023/04/13"]
},{
    "idno":2,
    "duration":2,
    "dates":["2023/04/11","2023/04/12"]
},{
    "idno":3,
    "duration":5,
    "dates":["2023/04/11","2023/04/12","2023/04/13","2023/04/14","2023/04/15"]
}]


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

Code (genero) Select

| IDNO | DURATION | DATE 01     | DATE 02     | DATE 03     | DATE 04     | DATE 05     | ...
| 0001 |     0003 | 2023/04/11  | 2023/04/12  | 2023/04/13  |             |             | ...
| 0002 |     0002 | 2023/04/11  | 2023/04/12  |             |             |             | ...
| 0003 |     0005 | 2023/04/11  | 2023/04/12  | 2023/04/13  | 2023/04/14  | 2023/04/15  | ...
Title: Re: Display An Array with Variable Number of Column
Post by: Reuben Barclay 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 (genero) Select
data dynamic array of record
  idno integer,
  duration integer,
  date_list string
end record


Code (genero) Select
| IDNO | DURATION | DATES
| 0001 |     0003 | 2023/04/11, 2023/04/12,  2023/04/13
| 0002 |     0002 | 2023/04/11, 2023/04/12
| 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 (genero) Select
data dynamic array of record
  idno integer,
  duration integer,
  date_count integer
end record


Code (genero) Select
| IDNO | DURATION | DATES
| 0001 |     0003 | 3 ^
| 0002 |     0002 | 2 ^
| 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 (genero) Select
data dynamic array of record
  idno integer,
  duration integer,
  date01 date,
  date02 date,
...
   date20 date
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 (genero) Select

LET max_date_count = 0
FOR i = 1 TO data.getLength()
   IF data[i].dates.getLength() > max_date_count THEN
       LET max_date_count = data[i].dates.getLength()
   END IF
END FOR

LET fields[1].name = "idno"
LET fields[1].type = "INTEGER"

LET fields[2].name = "duration"
LET fields[2].type = "INTEGER"

LET max_date_count =
FOR i = 1 TO max_date_count
   LET fields[i+2].name = "date", i USING "&&"
   LET fields[i+2].type = "DATE"
END FOR
...
LET d = ui.Dialog.createDisplayArrayTo(fields, "scr")


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 (genero) Select
FOR i = 1 TO data.getLength()
    CALL d.setCurrentRow("scr", i)
    CALL d.setFieldValue( "idno", data[i].idno)
    CALL d,setFieldValue("duration", data[i].duration)
    FOR j = 1 TO data[i].dates.getLength()
        CALL d.setFieldValue(SFMT("date%1", j USING "&&"), data[i].dates[j])
    END FOR
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 (genero) Select
| IDNO | DURATION | DATES
| 0001 |     0003 | 2023/04/11, 2023/04/12,  2023/04/13   ^
| 0002 |     0002 | 2023/04/11, 2023/04/12                 ^
| 0003 |     0005 | 5 dates from 2023/04/11 to 2023/04/15 ^


Hope this helps,

Reuben