Something like `table1.data` that reflects unsaved updates?

I'm tracking consecutive and non-overlapping durations that shouldn't have gaps between them. For example, it might be how many days I wear a given outfit before I throw it in the washing machine and put on a new one. The durations are consecutive and non-overlapping, because there are no days where I'm going out naked (hopefully?) and where I'm wearing two outfits. Currently, I have a table with one row for each duration defined by a start date and end date column. I'd like to prevent inserting rows with overlapping durations or rows whose durations has gaps to the previous or next rows into the database.

For adding new rows, this can be done with input validation on the input fields. The default value of the start date column is set to the end date of the most recent row and editing is disabled. Also, the min date of the end date is set to the start date to prevent negative durations. Dates, dates, more dates - date inception!

However, for updating existing rows this isn't so straight forward. If we add input validation to fix the start date to the end date of the previous row and the end date to the start date of the next row, we can't edit rows in the middle without first editing every other row starting from the first and last rows. It's like moving a rigid chain.

Instead, we want to separate input validation ("validation rules") from submit validation ("only run when"). We can only use input validation to check that the duration isn't negative, by setting the start date of a row must be smaller or equal to the end date and vice versa the end date must be greater or equal to the start date. Checking that there are no gaps or overlaps between consecutive durations needs to be done in the submit validation.

Still here?

This is where I'm stuck. There doesn't seem to be a way to get the updated table with unsaved changes since table1.data, table1.selectedRow, and co. all give the outdated data. A workaround could be to deep merge table1.data with the table1.changesetArray but that doesn't look like a user-friendly option to me.

Finally, here's my half question and half feature request: Is there something like table1.data that reflects unsaved updates?

1 Like

Here's the workaround for the input validation

  1. Define variable table1_selectedRow_uptodate
{{ table1.selectedRows.map(row => ({...row, ...table1.changesetArray.find(rowNew => rowNew.id === row.id)}))[0] }}
  1. Set "Max date" of start date column to
{{ table1_selectedRow_uptodate.value.endDate }}
  1. Set "Min date" of end date column to
{{ table1_selectedRow_uptodate.value.startDate }}

Here's the workaround for the submit validation

  1. Define variable table1_updated
{{ table1.data.map(row => ({...row, ...log_table.changesetArray.find(rowNew => rowNew.id === row.id)})) }}
  1. Define variable is_durations_valid

note: the table is assumed to be ordered with new on top, otherwise invert the logic.

{{ table1_uptodate.value.every((val, index, array) => {
  if (index < array.length - 1) {
    const nextItem = array[index + 1];
    if (val.startDate != nextItem.exit) {
      return false;
    }
  }
  
  if (index > 0) {
    const previousItem = array[index - 1];
    if (val.endDate != previousItem.entry) {
      return false;
    }
  }

  return true;
}) }}
  1. Set "Only run when" of the save handler that triggers the update query to
{{ is_durations_valid.value }}
1 Like

Hi @owj! Thanks for reaching out!

As far as a property that merges the table data with the pending changes, we don't currently expose this :disappointed: (there are performance considerations when adding properties to the table) Could you use some Javascript like this: table1.data.filter(x=>formatDataAsObject(table1.changesetArray).id.includes(x.id)).map(x=>_.merge(x, table1.changesetArray.filter(y=>y.id===x.id)[0]) ) :crossed_fingers: