Submit button not working as I expect

Hi all, 

I have an interface that displays an editable grid - representing a timesheet and the days of the week - Monday to Friday. The interface is part of a site. The idea is, an employee can enter their start time, finish time, lunch break etc and that data will be sent to a database when the user clicks the submit button. They can keep doing this as many times as they want and the data should stay consistent as the user clicks the submit button. The problem is, this doesn't happen. After clicking the submit button, the data is sent to the database correctly but the grid is populated with the default values instead of the values I just set. The correct, database values will only be displayed if I refresh the browser.

My theory is that when I click the submit button, the process (which updates the database) fires and before it can finish, the page reloads with default data because it couldn't find anything in the database. Is my theory correct? If so, what can be done? If not, what am I missing? I don't want to tell the user they have to refresh the browser to see their changes.

Here is my code for the interface:

load(
  local!headerCells: {
    a!gridLayoutHeaderCell(
      label: "Day"
    ),
    a!gridLayoutHeaderCell(
      label: "Start",
      align: "CENTER"
    ),
    a!gridLayoutHeaderCell(
      label: "Finish",
      align: "CENTER"
    ),
    a!gridLayoutHeaderCell(
      label: "Total",
      align: "CENTER"
    ),
    a!gridLayoutHeaderCell(
      label: "Lunch",
      align: "CENTER"
    ),
    a!gridLayoutHeaderCell(
      label: "Credits",
      align: "CENTER"
    ),
    a!gridLayoutHeaderCell(
      label: "Holiday and other paid leave",
      align: "CENTER"
    ),
    a!gridLayoutHeaderCell(
      label: "Net Hours",
      align: "CENTER"
    )
  },
  local!columnConfigs: {
    a!gridLayoutColumnConfig(
      weight: 3
    ),
    a!gridLayoutColumnConfig(
      weight: 1
    ),
    a!gridLayoutColumnConfig(
      weight: 1
    ),
    a!gridLayoutColumnConfig(
      weight: 1
    ),
    a!gridLayoutColumnConfig(
      weight: 1
    ),
    a!gridLayoutColumnConfig(
      weight: 1
    ),
    a!gridLayoutColumnConfig(
      weight: 8
    ),
    a!gridLayoutColumnConfig(
      weight: 1
    ),
    a!gridLayoutColumnConfig(
      width: "ICON"
    )
  },
  local!pagingInfo: a!pagingInfo(
    startIndex: 1,
    batchSize: - 1
  ),
  local!defaultTime: "00:00",
  local!defaultStartTime: "09:00",
  local!defaultFinishTime: "17:00",
  local!defaultLunch: "00:30",
  local!employeeId: user(
    loggedInUser(),
    "customField1"
  ),
  local!endOfWeekDate: rule!Flexi_Time_getEndOfWeekDate(
    today()
  ),
  /*Get all dates for selected week */
  local!selectedDateRange: rule!Flexi_Time_getWeekDateArray(
    local!endOfWeekDate
  ),
  /*Get Timesheet Id */
  local!timesheetId: rule!Flexi_Time_fetchTimesheetForEmployeeIdAndPeriodDates(
    employeeId: local!employeeId,
    startDate: rule!Flexi_Time_getTimesheetPeriodDates(
      local!selectedDateRange
    ).startDate,
    endDate: rule!Flexi_Time_getTimesheetPeriodDates(
      local!selectedDateRange
    ).endDate
  ).timesheetId,
  /*Get Workweek Id */
  local!workweekId: with(
    local!data: rule!Flexi_Time_getCombinedTimesheetField(
      local!employeeId,
      local!selectedDateRange,
      "workweekId"
    ),
    if(
      rule!APN_isEmpty(
        local!data
      ),
      null,
      local!data.workweekId
    )
  ),
  /*Determine if a timesheet needs to be created or if one already exists for current period */
  local!timesheetIsRequired: rule!Flexi_Time_requiresTimesheet(
    employeeId: local!employeeId,
    dates: local!selectedDateRange
  ),
  /*Determine if a workweek needs to be created */
  local!workweekIsRequired: rule!APN_isEmpty(
    local!workweekId
  ),
  /*Get all workdays that exist in DB for selected week, otherwise build empty/default ones */
  local!workdays: a!forEach(
    items: local!selectedDateRange,
    expression: with(
      local!workday: rule!Flexi_Time_getEmployeeWorkday(
        fv!item,
        local!employeeId
      ),
      if(
        rule!APN_isEmpty(
          local!workday.workdayId
        ),
        rule!Flexi_Time_buildEmptyWorkdayCDT(
          workweekId: local!workweekId,
          date: fv!item,
          startTime: local!defaultStartTime,
          finishTime: local!defaultFinishTime,
          lunch: local!defaultLunch
        ),
        local!workday
      )
    )
  ),

  a!formLayout(
    contents: {
      a!boxLayout(
        label: "Summary",
        contents: {},
        style: "INFO",
        marginBelow: "STANDARD"
      ),
      a!boxLayout(
        label: "Weekly Timesheets",
        contents: {
          a!sideBySideLayout(
            items: {
              a!sideBySideItem(
                item: a!richTextDisplayField(
                  value: a!richTextImage(
                    image: a!documentImage(
                      document: cons!FLEXI_TIME_LEFTARROWICON,
                      /*alternate appian icon: */
                      /*document: a!iconIndicator("MOVE_LEFT"), */
                      altText: "N/A",
                      caption: "View previous week",
                      link: a!dynamicLink(
                        saveInto: {
                          a!save(
                            local!endOfWeekDate,
                            local!endOfWeekDate - 7
                          ),
                          a!save(
                            local!selectedDateRange,
                            rule!Flexi_Time_getWeekDateArray(
                              local!endOfWeekDate
                            )
                          ),
                          a!save(
                            local!timesheetId,
                            rule!Flexi_Time_fetchTimesheetForEmployeeIdAndPeriodDates(
                              employeeId: local!employeeId,
                              startDate: rule!Flexi_Time_getTimesheetPeriodDates(
                                local!selectedDateRange
                              ).startDate,
                              endDate: rule!Flexi_Time_getTimesheetPeriodDates(
                                local!selectedDateRange
                              ).endDate
                            ).timesheetId
                          ),
                          a!save(
                            local!workweekId,
                            with(
                              local!data: rule!Flexi_Time_getCombinedTimesheetField(
                                local!employeeId,
                                local!selectedDateRange,
                                "workweekId"
                              ),
                              if(
                                rule!APN_isEmpty(
                                  local!data
                                ),
                                null,
                                local!data.workweekId
                              )
                            )
                          ),
                          a!save(
                            local!timesheetIsRequired,
                            rule!Flexi_Time_requiresTimesheet(
                              employeeId: local!employeeId,
                              dates: local!selectedDateRange
                            )
                          ),
                          a!save(
                            local!workweekIsRequired,
                            rule!APN_isEmpty(
                              local!workweekId
                            )
                          ),
                          a!forEach(
                            local!workdays,
                            a!save(
                              fv!item,
                              with(
                                local!workday: rule!Flexi_Time_getEmployeeWorkday(
                                  local!selectedDateRange[fv!index],
                                  local!employeeId
                                ),
                                if(
                                  rule!APN_isEmpty(
                                    local!workday.workdayId
                                  ),
                                  rule!Flexi_Time_buildEmptyWorkdayCDT(
                                    workweekId: local!workweekId,
                                    date: local!selectedDateRange[fv!index],
                                    startTime: local!defaultStartTime,
                                    finishTime: local!defaultFinishTime,
                                    lunch: local!defaultLunch
                                  ),
                                  local!workday
                                )
                              )
                            )
                          )
                        }
                      )
                    )
                  ),
                  align: "LEFT"
                )
              ),
              a!sideBySideItem(
                item: a!dateField(
                  label: "Week Ending",
                  labelPosition: "ADJACENT",
                  value: local!endOfWeekDate,
                  saveInto: {
                    a!save(
                      local!endOfWeekDate,
                      rule!Flexi_Time_getEndOfWeekDate(
                        save!value
                      )
                    ),
                    a!save(
                      local!selectedDateRange,
                      rule!Flexi_Time_getWeekDateArray(
                        local!endOfWeekDate
                      )
                    ),
                    a!save(
                      local!timesheetId,
                      rule!Flexi_Time_fetchTimesheetForEmployeeIdAndPeriodDates(
                        employeeId: local!employeeId,
                        startDate: rule!Flexi_Time_getTimesheetPeriodDates(
                          local!selectedDateRange
                        ).startDate,
                        endDate: rule!Flexi_Time_getTimesheetPeriodDates(
                          local!selectedDateRange
                        ).endDate
                      ).timesheetId
                    ),
                    a!save(
                      local!workweekId,
                      with(
                        local!data: rule!Flexi_Time_getCombinedTimesheetField(
                          local!employeeId,
                          local!selectedDateRange,
                          "workweekId"
                        ),
                        if(
                          rule!APN_isEmpty(
                            local!data
                          ),
                          null,
                          local!data.workweekId
                        )
                      )
                    ),
                    a!save(
                      local!timesheetIsRequired,
                      rule!Flexi_Time_requiresTimesheet(
                        employeeId: local!employeeId,
                        dates: local!selectedDateRange
                      )
                    ),
                    a!save(
                      local!workweekIsRequired,
                      rule!APN_isEmpty(
                        local!workweekId
                      )
                    ),
                    a!forEach(
                      local!workdays,
                      a!save(
                        fv!item,
                        with(
                          local!workday: rule!Flexi_Time_getEmployeeWorkday(
                            local!selectedDateRange[fv!index],
                            local!employeeId
                          ),
                          if(
                            rule!APN_isEmpty(
                              local!workday.workdayId
                            ),
                            rule!Flexi_Time_buildEmptyWorkdayCDT(
                              workweekId: local!workweekId,
                              date: local!selectedDateRange[fv!index],
                              startTime: local!defaultStartTime,
                              finishTime: local!defaultFinishTime,
                              lunch: local!defaultLunch
                            ),
                            local!workday
                          )
                        )
                      )
                    )
                  },
                  align: "CENTER"
                )
              ),
              a!sideBySideItem(
                item: a!richTextDisplayField(
                  value: a!richTextImage(
                    image: a!documentImage(
                      document: cons!FLEXI_TIME_RIGHTARROWICON,
                      /*alternate appian icon: */
                      /*document: a!iconIndicator("MOVE_RIGHT"), */
                      altText: "N/A",
                      caption: "View next week",
                      link: a!dynamicLink(
                        saveInto: {
                          a!save(
                            local!endOfWeekDate,
                            local!endOfWeekDate + 7
                          ),
                          a!save(
                            local!selectedDateRange,
                            rule!Flexi_Time_getWeekDateArray(
                              local!endOfWeekDate
                            )
                          ),
                          a!save(
                            local!timesheetId,
                            rule!Flexi_Time_fetchTimesheetForEmployeeIdAndPeriodDates(
                              employeeId: local!employeeId,
                              startDate: rule!Flexi_Time_getTimesheetPeriodDates(
                                local!selectedDateRange
                              ).startDate,
                              endDate: rule!Flexi_Time_getTimesheetPeriodDates(
                                local!selectedDateRange
                              ).endDate
                            ).timesheetId
                          ),
                          a!save(
                            local!workweekId,
                            with(
                              local!data: rule!Flexi_Time_getCombinedTimesheetField(
                                local!employeeId,
                                local!selectedDateRange,
                                "workweekId"
                              ),
                              if(
                                rule!APN_isEmpty(
                                  local!data
                                ),
                                null,
                                local!data.workweekId
                              )
                            )
                          ),
                          a!save(
                            local!timesheetIsRequired,
                            rule!Flexi_Time_requiresTimesheet(
                              employeeId: local!employeeId,
                              dates: local!selectedDateRange
                            )
                          ),
                          a!save(
                            local!workweekIsRequired,
                            rule!APN_isEmpty(
                              local!workweekId
                            )
                          ),
                          a!forEach(
                            local!workdays,
                            a!save(
                              fv!item,
                              with(
                                local!workday: rule!Flexi_Time_getEmployeeWorkday(
                                  local!selectedDateRange[fv!index],
                                  local!employeeId
                                ),
                                if(
                                  rule!APN_isEmpty(
                                    local!workday.workdayId
                                  ),
                                  rule!Flexi_Time_buildEmptyWorkdayCDT(
                                    workweekId: local!workweekId,
                                    date: local!selectedDateRange[fv!index],
                                    startTime: local!defaultStartTime,
                                    finishTime: local!defaultFinishTime,
                                    lunch: local!defaultLunch
                                  ),
                                  local!workday
                                )
                              )
                            )
                          )
                        }
                      )
                    )
                  ),
                  align: "RIGHT"
                )
              )
            },
            alignVertical: "MIDDLE"
          ),
          a!gridLayout(
            headerCells: append(
              local!headerCells,
              a!gridLayoutHeaderCell(
                label: ""
              )
            ),
            columnConfigs: local!columnConfigs,
            rows: {
              a!forEach(
                local!workdays,
                rule!Flexi_Time_TimesheetGridRow(
                  dayOfWeek: rule!Flexi_Time_displayDayOfWeek(
                    local!selectedDateRange[fv!index]
                  ),
                  startTime: fv!item.startTime,
                  finishTime: fv!item.finishTime,
                  totalTime: fv!item.totalHours,
                  lunchTime: fv!item.lunch,
                  credits: fv!item.credits,
                  leave: fv!item.paidLeave,
                  netHours: fv!item.netHours
                )
              )
            }
          )
        },
        style: "INFO",
        marginBelow: "STANDARD"
      ),
      a!buttonLayout(
        primaryButtons: {
          a!buttonWidget(
            label: "SAVE WEEK",
            style: "PRIMARY",
            saveInto: {
              a!save(
                ri!workdays,
                local!workdays
              ),
              a!save(
                ri!workweekIsRequired,
                local!workweekIsRequired
              ),
              a!save(
                ri!timesheetIsRequired,
                local!timesheetIsRequired
              ),
              a!save(
                ri!workweekId,
                local!workweekId
              ),
              a!save(
                ri!timesheetId,
                local!timesheetId
              ),
              a!save(
                ri!selectedDateRange,
                local!selectedDateRange
              ),
              a!save(
                ri!employeeId,
                local!employeeId
              )
            },
            submit: true
          )
        }
      )
    }
  )
)

Thanks for your help Appian community!

  Discussion posts and replies are publicly visible

Parents
  • 0
    Certified Lead Developer

    Set default values into a PV, use the PV as your ACP for the user input task.  Configure the SavedValues output of your database write node to store the saved values into THAT PV.  Also set a boolean for another PV isDatabaseDoneWriting (or something like it) to true.

    Next, add a node that the process parks at until it either times out (after enough time to convince you the database write is clearly broken) or that PV comes true, then loop back into your user input task.  The trouble is, once the user input task starts, you can't change any of the variables it has without referencing the PVs directly in the SAIL and not passing through ACs, which isn't standard practice.  And even those won't update your SAIL unless your user interacts with something.  This means your form could have bad data preloaded, then jump suddenly to good data when the user clicks, which would be confusing and less than ideal experience.  Best to make sure you're operating on saved values and ensure that the write is done before you synch up.

    It might be better, depending on how long the write is, to make the DB write synchronous.  If you have other stuff you could be doing at the same time, you could have a parallel flow that comes to a Complex gate that requires both flows to finish before proceeding back to the user input task.  It could say "Working" for a noticably long time, but you'll have correct data when it refreshes.  If the "Working" isn't too long that would be a better experience.

Reply
  • 0
    Certified Lead Developer

    Set default values into a PV, use the PV as your ACP for the user input task.  Configure the SavedValues output of your database write node to store the saved values into THAT PV.  Also set a boolean for another PV isDatabaseDoneWriting (or something like it) to true.

    Next, add a node that the process parks at until it either times out (after enough time to convince you the database write is clearly broken) or that PV comes true, then loop back into your user input task.  The trouble is, once the user input task starts, you can't change any of the variables it has without referencing the PVs directly in the SAIL and not passing through ACs, which isn't standard practice.  And even those won't update your SAIL unless your user interacts with something.  This means your form could have bad data preloaded, then jump suddenly to good data when the user clicks, which would be confusing and less than ideal experience.  Best to make sure you're operating on saved values and ensure that the write is done before you synch up.

    It might be better, depending on how long the write is, to make the DB write synchronous.  If you have other stuff you could be doing at the same time, you could have a parallel flow that comes to a Complex gate that requires both flows to finish before proceeding back to the user input task.  It could say "Working" for a noticably long time, but you'll have correct data when it refreshes.  If the "Working" isn't too long that would be a better experience.

Children
No Data