private async void OnButtonClick(Button button, ChildElement elementData) { button.IsEnabled = false; IsBusy = true; try { string outcomePathName = elementData.Child.OutcomePathName; string validationMessage = ""; if (!FormService.Validate(controls, outcomePathName, out validationMessage)) { await DisplayAlert("Validation Issues", validationMessage, "OK"); return; } var data = FormUtils.CollectData(controls); if (Connectivity.NetworkAccess == NetworkAccess.Internet) { DecisionsFormInfoEvent e = await FormService.SelectPath(viewModel.FormInfo.FormSessionInfoId, outcomePathName, data, useNamedSession); Debug.Write(e); if (e == null) { await DisplayAlert("Error", "Problem with next form instruction.", "OK"); return; } var validationMessages = e.GetValidationMessages(); if (validationMessages.Length > 0) { string message = ""; Array.ForEach(validationMessages, msg => message += $"{msg}.\n\n"); await DisplayAlert("Validation Issues", message, "OK"); // TODO highlight the offending components Array.ForEach(e.CurrentValidations, validation => { FormControlWrapper control; controls.TryGetValue(validation.ComponentID, out control); // just show breaking issues for cut 1: var breakingIssue = Array.Find(validation.ValidationIssues, issue => issue.BreakLevel == BreakLevel.Fatal); if (control != null && breakingIssue != null) { control.SetValidation(breakingIssue.BreakLevel); } }); } // if there were no validations to show, there should be next instructions if (e.IsFlowCompletedInstructionEvent()) { // Close this page. The flow's forms are done. viewModel.Submitted = true; await Navigation.PopAsync(); DependencyService.Get <ISnackbar>().ShortAlert("Form submitted successfully."); } else if (!String.IsNullOrEmpty(e.FlowTrackingId) && !String.IsNullOrEmpty(e.StepTrackingId)) { var flowInstr = await FlowExecutionService.GetInstructionsForStep(e.FlowTrackingId, e.StepTrackingId, useNamedSession); if (FlowExecutionService.IsShowFormType(flowInstr)) { // render the next form in this page. ShowNextForm(flowInstr); } else { // close this page? Not sure how we'd get here... Console.WriteLine("Found Next Instruction was not a form instruction!"); viewModel.Submitted = true; await Navigation.PopAsync(); DependencyService.Get <ISnackbar>().ShortAlert("Form submitted successfully."); if (useNamedSession) { MessagingCenter.Send(this, Message.ACCOUNT_CREATED); } } } else { // did I missunderstand the structure? Debug.WriteLine(e); } } else { if (viewModel.CanRunOffline) { var ret = await OfflineService.Instance.SaveOfflineFormSubmission(viewModel.ServiceCategoryId, data, outcomePathName, viewModel.FormInfo.FormRules); viewModel.Submitted = true; await Navigation.PopAsync(); DependencyService.Get <ISnackbar>().ShortAlert("Form saved, and will submit when online."); } else { await DisplayAlert("Error", "Connection lost. Please, try again later.", "OK"); } } } catch (Exception ex) { Debug.WriteLine("FormPage Submit---", ex.Message); await DisplayAlert("Error", "Something went wrong! Please try again later.", "OK"); } finally { IsBusy = false; button.IsEnabled = true; } }