diff --git a/src/UDS.Net.Forms.Tests/UDS.Net.Forms.Tests.csproj b/src/UDS.Net.Forms.Tests/UDS.Net.Forms.Tests.csproj index d28382cd..422fd3b9 100644 --- a/src/UDS.Net.Forms.Tests/UDS.Net.Forms.Tests.csproj +++ b/src/UDS.Net.Forms.Tests/UDS.Net.Forms.Tests.csproj @@ -5,7 +5,7 @@ enable enable false - 4.1.3 + 4.2.0 diff --git a/src/UDS.Net.Forms/DataAnnotations/RequiredIfInPersonVisitAttribute.cs b/src/UDS.Net.Forms/DataAnnotations/RequiredIfInPersonVisitAttribute.cs new file mode 100644 index 00000000..5bf16f29 --- /dev/null +++ b/src/UDS.Net.Forms/DataAnnotations/RequiredIfInPersonVisitAttribute.cs @@ -0,0 +1,92 @@ +using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UDS.Net.Forms.Models; +using UDS.Net.Services.Enums; + +namespace UDS.Net.Forms.DataAnnotations +{ + [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] + public class RequiredIfInPersonVisitAttribute : ValidationAttribute, IClientModelValidator + { + private string _watchedField = ""; + private string _watchedFieldValue = ""; + + public RequiredIfInPersonVisitAttribute(string watchedField, string value) : base() + { + _watchedField = watchedField; + _watchedFieldValue = value; + } + protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) + { + // does the form have a status and is it attempting to be finalized? + if (validationContext.ObjectType.IsSubclassOf(typeof(FormModel))) + { + var form = (FormModel)validationContext.ObjectInstance; + + // only validate if the form is attempting to be completed + if (form.Status == FormStatus.Finalized) + + if (form.MODE == FormMode.InPerson || form.RMMODE == RemoteModality.Video) + { + // get the watched property and compare + var type = validationContext.ObjectType; + + if (type != null) + { + var watchedProperty = type.GetProperty(_watchedField); + + if (watchedProperty != null) + { + var currentValue = watchedProperty.GetValue(validationContext.ObjectInstance, null); + if (currentValue != null) + { + if (currentValue.ToString() == _watchedFieldValue) + { + // if the watched field's value matches what we're looking for then this field requires a value + if (value == null) + return new ValidationResult(this.ErrorMessage); + } + } + } + } + } + } + + + return ValidationResult.Success; + } + + public void AddValidation(ClientModelValidationContext context) + { + MergeAttribute(context.Attributes, "data-val", "true"); + MergeAttribute(context.Attributes, "data-val-requiredif", this.ErrorMessage); + string watched = _watchedField; + var containerName = context.ModelMetadata.ContainerType.Name; + if (!String.IsNullOrEmpty(containerName)) + { + watched = containerName + "." + _watchedField; + } + MergeAttribute(context.Attributes, "data-val-requiredif-watchedfield", watched); + MergeAttribute(context.Attributes, "data-val-requiredif-watchedfieldvalue", _watchedFieldValue); + } + + /// + /// See https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-7.0#iclientmodelvalidator-for-client-side-validation + /// + private static bool MergeAttribute(IDictionary attributes, string key, string value) + { + if (attributes.ContainsKey(key)) + { + return false; + } + + attributes.Add(key, value); + return true; + } + } +} diff --git a/src/UDS.Net.Forms/DataAnnotations/RequiredIfTelephoneVisitAttribute.cs b/src/UDS.Net.Forms/DataAnnotations/RequiredIfTelephoneVisitAttribute.cs new file mode 100644 index 00000000..64f19cbc --- /dev/null +++ b/src/UDS.Net.Forms/DataAnnotations/RequiredIfTelephoneVisitAttribute.cs @@ -0,0 +1,90 @@ +using Microsoft.AspNetCore.Mvc.ModelBinding.Validation; +using System; +using System.Collections.Generic; +using System.ComponentModel.DataAnnotations; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using UDS.Net.Forms.Models; +using UDS.Net.Services.Enums; + +namespace UDS.Net.Forms.DataAnnotations +{ + [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] + public class RequiredIfTelephoneVisitAttribute : ValidationAttribute, IClientModelValidator + { + private string _watchedField = ""; + private string _watchedFieldValue = ""; + + public RequiredIfTelephoneVisitAttribute(string watchedField, string value) : base() + { + _watchedField = watchedField; + _watchedFieldValue = value; + } + protected override ValidationResult? IsValid(object? value, ValidationContext validationContext) + { + // does the form have a status and is it attempting to be finalized? + if (validationContext.ObjectType.IsSubclassOf(typeof(FormModel))) + { + var form = (FormModel)validationContext.ObjectInstance; + + // only validate if the form is attempting to be completed + if (form.Status == FormStatus.Finalized && form.RMMODE == RemoteModality.Telephone) + { + // get the watched property and compare + var type = validationContext.ObjectType; + + if (type != null) + { + var watchedProperty = type.GetProperty(_watchedField); + + if (watchedProperty != null) + { + var currentValue = watchedProperty.GetValue(validationContext.ObjectInstance, null); + if (currentValue != null) + { + if (currentValue.ToString() == _watchedFieldValue) + { + // if the watched field's value matches what we're looking for then this field requires a value + if (value == null) + return new ValidationResult(this.ErrorMessage); + } + } + } + } + } + } + + + return ValidationResult.Success; + } + + public void AddValidation(ClientModelValidationContext context) + { + MergeAttribute(context.Attributes, "data-val", "true"); + MergeAttribute(context.Attributes, "data-val-requiredif", this.ErrorMessage); + string watched = _watchedField; + var containerName = context.ModelMetadata.ContainerType.Name; + if (!String.IsNullOrEmpty(containerName)) + { + watched = containerName + "." + _watchedField; + } + MergeAttribute(context.Attributes, "data-val-requiredif-watchedfield", watched); + MergeAttribute(context.Attributes, "data-val-requiredif-watchedfieldvalue", _watchedFieldValue); + } + + /// + /// See https://learn.microsoft.com/en-us/aspnet/core/mvc/models/validation?view=aspnetcore-7.0#iclientmodelvalidator-for-client-side-validation + /// + private static bool MergeAttribute(IDictionary attributes, string key, string value) + { + if (attributes.ContainsKey(key)) + { + return false; + } + + attributes.Add(key, value); + return true; + } + } +} diff --git a/src/UDS.Net.Forms/Extensions/DomainToViewModelMapper.cs b/src/UDS.Net.Forms/Extensions/DomainToViewModelMapper.cs index a5200a32..44f6e26f 100644 --- a/src/UDS.Net.Forms/Extensions/DomainToViewModelMapper.cs +++ b/src/UDS.Net.Forms/Extensions/DomainToViewModelMapper.cs @@ -1257,6 +1257,7 @@ public static C2 ToVM(this C2FormFields fields, int formId) MOCAVIS = fields.MOCAVIS, MOCAHEAR = fields.MOCAHEAR, MOCATOTS = fields.MOCATOTS, + MOCBTOTS = fields.MOCBTOTS, MOCATRAI = fields.MOCATRAI, MOCACUBE = fields.MOCACUBE, MOCACLOC = fields.MOCACLOC, @@ -1354,6 +1355,12 @@ public static C2 ToVM(this C2FormFields fields, int formId) CERADJ6INT = fields.CERADJ6INT, CERADJ7YES = fields.CERADJ7YES, CERADJ7NO = fields.CERADJ7NO, + OTRAILA = fields.OTRAILA, + OTRLARR = fields.OTRLARR, + OTRLALI = fields.OTRLALI, + OTRAILB = fields.OTRAILB, + OTRLBRR = fields.OTRLBRR, + OTRLBLI = fields.OTRLBLI, VNTTOTW = fields.VNTTOTW, VNTPCNC = fields.VNTPCNC, RESPVAL = fields.RESPVAL, diff --git a/src/UDS.Net.Forms/Extensions/ViewModelToDomainMapper.cs b/src/UDS.Net.Forms/Extensions/ViewModelToDomainMapper.cs index c1f1f4af..0506c5a9 100644 --- a/src/UDS.Net.Forms/Extensions/ViewModelToDomainMapper.cs +++ b/src/UDS.Net.Forms/Extensions/ViewModelToDomainMapper.cs @@ -942,6 +942,7 @@ public static IFormFields GetFormFields(this C2 vm) MOCAVIS = vm.MOCAVIS, MOCAHEAR = vm.MOCAHEAR, MOCATOTS = vm.MOCATOTS, + MOCBTOTS = vm.MOCBTOTS, MOCATRAI = vm.MOCATRAI, MOCACUBE = vm.MOCACUBE, MOCACLOC = vm.MOCACLOC, @@ -1039,6 +1040,12 @@ public static IFormFields GetFormFields(this C2 vm) CERADJ6INT = vm.CERADJ6INT, CERADJ7YES = vm.CERADJ7YES, CERADJ7NO = vm.CERADJ7NO, + OTRAILA = vm.OTRAILA, + OTRLARR = vm.OTRLARR, + OTRLALI = vm.OTRLALI, + OTRAILB = vm.OTRAILB, + OTRLBRR = vm.OTRLBRR, + OTRLBLI = vm.OTRLBLI, VNTTOTW = vm.VNTTOTW, VNTPCNC = vm.VNTPCNC, RESPVAL = vm.RESPVAL, diff --git a/src/UDS.Net.Forms/Models/PageModels/FormPageModel.cs b/src/UDS.Net.Forms/Models/PageModels/FormPageModel.cs index 83571abb..b557617d 100644 --- a/src/UDS.Net.Forms/Models/PageModels/FormPageModel.cs +++ b/src/UDS.Net.Forms/Models/PageModels/FormPageModel.cs @@ -109,6 +109,26 @@ protected async Task OnPostAsync(int id) Visit = visit.ToVM(); + if (BaseForm.Kind == "C2") + { + if (BaseForm != null) + { + var C2 = new C2Model(_visitService); + + C2.Visit = Visit; + C2.BaseForm = BaseForm; + C2.C2 = (C2)BaseForm; + + var form = visit.Forms.Where(f => f.Kind == _formKind).FirstOrDefault(); + + if (!ModelState.IsValid) + { + Response.ContentType = "text/vnd.turbo-stream.html"; + return Partial("_C2Validation", C2); + } + }; + } + return Page(); } diff --git a/src/UDS.Net.Forms/Models/UDS4/C2.cs b/src/UDS.Net.Forms/Models/UDS4/C2.cs index 34bd0c02..082f03f9 100644 --- a/src/UDS.Net.Forms/Models/UDS4/C2.cs +++ b/src/UDS.Net.Forms/Models/UDS4/C2.cs @@ -24,7 +24,7 @@ public class C2 : FormModel public int? MOCAREAS { get; set; } [Display(Name = "MoCA was administered")] - [RequiredIf(nameof(MOCACOMP), "1", ErrorMessage = "Which MoCA was administered?")] + [RequiredIfInPersonVisit(nameof(MOCACOMP), "1", ErrorMessage = "Which MoCA was administered?")] public int? MOCALOC { get; set; } [Display(Name = "Language of MoCA administration")] @@ -46,42 +46,46 @@ public class C2 : FormModel [Display(Name = "Total Raw Score - Uncorrected", Description = "(0-30,88)")] [RegularExpression("^(\\d|[0-2]\\d|30|88)$", ErrorMessage = "Allowed values are 0-30 or 88 = not administered.")] - [RequiredIf(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] + [RequiredIfInPersonVisit(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] public int? MOCATOTS { get; set; } + [Display(Name = "Total Raw Score - Uncorrected", Description = "(0-22,88)")] + [RegularExpression("^(\\d|1\\d|2[0-2]|88)$", ErrorMessage = "Allowed values are 0-22 or 88 = not administered.")] + public int? MOCBTOTS { get; set; } + [Display(Name = "Visuospatial/executive — Trails", Description = "(0-1, 95-98)")] [RegularExpression("^([0-1]|9[5-8])$", ErrorMessage = "Allowed values are 0-1 or 95-98.")] - [RequiredIf(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] + [RequiredIfInPersonVisit(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] public int? MOCATRAI { get; set; } [Display(Name = " Visuospatial/executive — Cube", Description = "(0-1, 95-98)")] [RegularExpression("^([0-1]|9[5-8])$", ErrorMessage = "Allowed values are 0-1 or 95-98.")] - [RequiredIf(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] + [RequiredIfInPersonVisit(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] public int? MOCACUBE { get; set; } [Display(Name = "Visuospatial/executive — Clock contour", Description = "(0-1, 95-98)")] [RegularExpression("^([0-1]|9[5-8])$", ErrorMessage = "Allowed values are 0-1 or 95-98.")] - [RequiredIf(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] + [RequiredIfInPersonVisit(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] public int? MOCACLOC { get; set; } [Display(Name = "Visuospatial/executive — Clock numbers", Description = "(0-1, 95-98)")] [RegularExpression("^([0-1]|9[5-8])$", ErrorMessage = "Allowed values are 0-1 or 95-98.")] - [RequiredIf(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] + [RequiredIfInPersonVisit(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] public int? MOCACLON { get; set; } [Display(Name = "Visuospatial/executive — Clock hands", Description = "(0-1, 95-98)")] [RegularExpression("^([0-1]|9[5-8])$", ErrorMessage = "Allowed values are 0-1 or 95-98.")] - [RequiredIf(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] + [RequiredIfInPersonVisit(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] public int? MOCACLOH { get; set; } [Display(Name = "Language — Naming", Description = "(0-3, 95-98)")] [RegularExpression("^([0-3]|9[5-8])$", ErrorMessage = "Allowed values are 0-3 or 95-98.")] - [RequiredIf(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] + [RequiredIfInPersonVisit(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] public int? MOCANAMI { get; set; } [Display(Name = "Memory — Registration (two trials)", Description = "(0-10, 95-98)")] [RegularExpression("^(\\d|10|9[5-8])$", ErrorMessage = "Allowed values are 0-10 or 95-98.")] - [RequiredIf(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] + [RequiredIfInPersonVisit(nameof(MOCACOMP), "1", ErrorMessage = "Response required")] public int? MOCAREGI { get; set; } [Display(Name = "Attention — Digits", Description = "(0-2, 95-98)")] @@ -164,7 +168,8 @@ public class C2 : FormModel public int? MOCAORCT { get; set; } [Display(Name = "The tests following the MoCA were administered")] - [RequiredOnFinalized] + [RequiredIf(nameof(RMMODE), "Video")] + [RequiredIf(nameof(MODE), "In-Person")] public int? NPSYCLOC { get; set; } [Display(Name = "Language of test administration")] @@ -193,7 +198,8 @@ public class C2 : FormModel [Display(Name = "Total Score for copy of Benson figure", Description = "(0-17, 95-98)")] [RegularExpression("^(\\d|1[0-7]|9[5-8])$", ErrorMessage = "Allowed values are 0-17 or 95-98.")] - [RequiredOnFinalized(ErrorMessage = "Provide Benson figure score")] + [RequiredIf(nameof(RMMODE), "Video")] + [RequiredIf(nameof(MODE), "In-Person")] public int? UDSBENTC { get; set; } #region if not completed, skip to 6a @@ -238,7 +244,9 @@ public class C2 : FormModel [Display(Name = "Part A: Total number of seconds to complete", Description = "(0-150, 995-998)")] [RegularExpression("^(\\d|[1-9]\\d|1[0-4]\\d|150|99[5-8])$", ErrorMessage = "Allowed values are 0-150 or 995-998.")] - [RequiredOnFinalized(ErrorMessage = "Provide number of seconds to complete")] + [RequiredIf(nameof(RMMODE), "Video")] + [RequiredIf(nameof(MODE), "In-Person")] + public int? TRAILA { get; set; } [Display(Name = "Number of commission errors", Description = "(0-40)")] @@ -257,7 +265,8 @@ public class C2 : FormModel [Display(Name = "Part B: Total number of seconds to complete", Description = "(0-300, 995-998)")] [RegularExpression("^(\\d|[1-9]\\d|[12]\\d{2}|300|99[5-8])$", ErrorMessage = "(0-300, 995-998)")] - [RequiredOnFinalized(ErrorMessage = "Response required")] + [RequiredIf(nameof(RMMODE), "Video")] + [RequiredIf(nameof(MODE), "In-Person")] public int? TRAILB { get; set; } [Display(Name = "Number of commission errors", Description = "(0-40)")] @@ -299,7 +308,8 @@ public class C2 : FormModel [Display(Name = "Total score for drawing of Benson figure following 10- to 15-minuted delay", Description = "(0-17, 95-98)")] [RegularExpression("^(\\d|1[0-7]|9[5-8])$", ErrorMessage = "Allowed values are 0-17 or 95-98.")] - [RequiredOnFinalized(ErrorMessage = "Provide score for drawing Benson figure")] + [RequiredIf(nameof(RMMODE), "Video")] + [RequiredIf(nameof(MODE), "In-Person")] public int? UDSBENTD { get; set; } [Display(Name = "Recognized original stimulus among four options?")] @@ -316,7 +326,8 @@ public class C2 : FormModel [Display(Name = "Total score", Description = "(0-32, 95-98)")] [RegularExpression("^(\\d|[12]\\d|3[0-2]|9[5-8])$", ErrorMessage = "Allowed values are 0-32 or 95-98.")] - [RequiredOnFinalized] + [RequiredIf(nameof(RMMODE), "Video")] + [RequiredIf(nameof(MODE), "In-Person")] public int? MINTTOTS { get; set; } [Display(Name = "Total correct without semantic cue", Description = "(0-32)")] @@ -573,13 +584,45 @@ public class C2 : FormModel [RegularExpression("^(\\d|10|9[5-8])$", ErrorMessage = "Allowed values are 0-10 or 95-98.")] public int? CERADJ7NO { get; set; } + [Display(Name = "Part A: Total number of seconds to complete", Description = "(0-100, 888, 995-998)")] + [RegularExpression("^(\\d{1,2}|100|888|99[5-8])$", ErrorMessage = "Allowed values are 0-100, 888, or 995-998.")] + [RequiredIf(nameof(RMMODE), "Telephone")] + public int? OTRAILA { get; set; } + + [Display(Name = "Part A - Number of commission errors", Description = "(0-99)")] + [RegularExpression("^\\d{1,2}$", ErrorMessage = "Allowed values are 0-99.")] + [RequiredIfRange(nameof(OTRAILA), 0, 100, ErrorMessage = "Response Required")] + public int? OTRLARR { get; set; } + + [Display(Name = "Part A - Number of correct lines", Description = "(0-25)")] + [RegularExpression("^(\\d|1\\d|2[0-5])$", ErrorMessage = "Allowed values are 0-25.")] + [RequiredIfRange(nameof(OTRAILA), 0, 100, ErrorMessage = "Response Required")] + public int? OTRLALI { get; set; } + + [Display(Name = "Part B: Total number of seconds to complete", Description = "(0-300, 888, 995-998)")] + [RegularExpression("^([0-9]|[1-9][0-9]|[12][0-9][0-9]|300|888|99[5-8])$", ErrorMessage = "Allowed values are 0-300, 888, or 995-998.")] + [RequiredIf(nameof(RMMODE), "Telephone")] + public int? OTRAILB { get; set; } + + [Display(Name = "Part B - Number of commission errors", Description = "(0-99)")] + [RegularExpression("^\\d{1,2}$", ErrorMessage = "Allowed values are 0-99.")] + [RequiredIfRange(nameof(OTRAILB), 0, 300, ErrorMessage = "Response Required")] + public int? OTRLBRR { get; set; } + + [Display(Name = "Number of correct lines", Description = "(0-25)")] + [RegularExpression("^(\\d|1\\d|2[0-5])$", ErrorMessage = "Allowed values are 0-25.")] + [RequiredIfRange(nameof(OTRAILB), 0, 300, ErrorMessage = "Response Required")] + public int? OTRLBLI { get; set; } + [Display(Name = "Total correct without a cue", Description = "(0-50, 88, 95-98)")] [RegularExpression("^(\\d|[1-4]\\d|50|88|9[5-8])$", ErrorMessage = "Allowed values are 0-50, 88 or 95-98.")] + [RequiredIf(nameof(RMMODE), "Telephone")] public int? VNTTOTW { get; set; } [Display(Name = "Total correct with a phonemic cue", Description = "(0-50, 88, 95-98)")] [RegularExpression("^(\\d|[1-4]\\d|50|88|9[5-8])$", ErrorMessage = "Allowed values are 0-50, 88 or 95-98.")] + [RequiredIf(nameof(RMMODE), "Telephone")] public int? VNTPCNC { get; set; } [Display(Name = "How valid do you think the participant’s responses are?")] @@ -635,26 +678,36 @@ public override IEnumerable Validate(ValidationContext validat { if (Status == Services.Enums.FormStatus.Finalized) { - // 1g-1l, 1n-1t, or 1w-1bb - if (MOCATOTS.HasValue && MOCATRAI.HasValue && MOCACUBE.HasValue && - MOCACLOC.HasValue && MOCACLON.HasValue && MOCACLOH.HasValue && - MOCANAMI.HasValue && MOCADIGI.HasValue && MOCALETT.HasValue && - MOCASER7.HasValue && MOCAREPE.HasValue && MOCAFLUE.HasValue && - MOCAABST.HasValue && MOCARECN.HasValue && MOCAORDT.HasValue && - MOCAORMO.HasValue && MOCAORYR.HasValue && MOCAORDY.HasValue && - MOCAORPL.HasValue && MOCAORCT.HasValue) + // If **any** of the following MoCA items were not administered: 1g –1l, 1n–1t, 1w–1bb, then MOCATOTS must be 88 + // 1g MOCATRAI + // 1h MOCACUBE + // 1i MOCACLOC + // 1j MOCACLON + // 1k MOCACLOH + // 1l MOCANAMI + // + // 1n MOCADIGI + // 1o MOCALETT + // 1p MOCASER7 + // 1q MOCAREPE + // 1r MOCAFLUE + // 1s MOCAABST + // 1t MOCARECN + // + // 1w MOCAORDT + // 1x MOCAORMO + // 1y MOCAORYR + // 1z MOCAORDY + // 1aa MOCAORPL + // 1bb MOCAORCT + if (MOCATOTS.HasValue && + ((MOCATRAI.HasValue && MOCATRAI.Value >= 95) || (MOCACUBE.HasValue && MOCACUBE.Value >= 95) || (MOCACLOC.HasValue && MOCACLOC.Value >= 95) || (MOCACLON.HasValue && MOCACLON.Value >= 95) || (MOCACLOH.HasValue && MOCACLOH.Value >= 95) || (MOCANAMI.HasValue && MOCANAMI.Value >= 95) + || (MOCADIGI.HasValue && MOCADIGI.Value >= 95) || (MOCALETT.HasValue && MOCALETT.Value >= 95) || (MOCASER7.HasValue && MOCASER7.Value >= 95) || (MOCAREPE.HasValue && MOCAREPE.Value >= 95) || (MOCAFLUE.HasValue && MOCAFLUE.Value >= 95) || (MOCAABST.HasValue && MOCAABST.Value >= 95) || (MOCARECN.HasValue && MOCARECN.Value >= 95) + || (MOCAORDT.HasValue && MOCAORDT.Value >= 95) || (MOCAORMO.HasValue && MOCAORMO.Value >= 95) || (MOCAORYR.HasValue && MOCAORYR.Value >= 95) || (MOCAORDY.HasValue && MOCAORDY.Value >= 95) || (MOCAORPL.HasValue && MOCAORPL.Value >= 95) || (MOCAORCT.HasValue && MOCAORCT.Value >= 95))) { - if (MOCATRAI.Value >= 95 && MOCACUBE.Value >= 95 && - MOCACLOC.Value >= 95 && MOCACLON.Value >= 95 && MOCACLOH.Value >= 95 && - MOCANAMI.Value >= 95 && MOCADIGI.Value >= 95 && MOCAFLUE.Value >= 95 && - MOCAABST.Value >= 95 && MOCARECN.Value >= 95 && MOCAORDT.Value >= 95 && - MOCAORMO.Value >= 95 && MOCAORYR.Value >= 95 && MOCAORDY.Value >= 95 && - MOCAORPL.Value >= 95 && MOCAORCT.Value >= 95) + if (MOCATOTS.Value != 88) { - if (MOCATOTS.Value != 88) - { - yield return new ValidationResult("If 1g-1l, 1n-1t, or 1w-1bb were not administered then MOCATOTS must be 88.", new[] { nameof(MOCATOTS) }); - } + yield return new ValidationResult("If 1g-1l, 1n-1t, or 1w-1bb were not administered then MOCATOTS must be 88.", new[] { nameof(MOCATOTS) }); } } diff --git a/src/UDS.Net.Forms/Pages/Participations/Create.cshtml b/src/UDS.Net.Forms/Pages/Participations/Create.cshtml index d331fd52..571ad7de 100644 --- a/src/UDS.Net.Forms/Pages/Participations/Create.cshtml +++ b/src/UDS.Net.Forms/Pages/Participations/Create.cshtml @@ -5,7 +5,7 @@ ViewData["Title"] = "Create participation"; } -
+
diff --git a/src/UDS.Net.Forms/Pages/Shared/_FormFooter.cshtml b/src/UDS.Net.Forms/Pages/Shared/_FormFooter.cshtml index 19e5e6a9..b8b565a9 100644 --- a/src/UDS.Net.Forms/Pages/Shared/_FormFooter.cshtml +++ b/src/UDS.Net.Forms/Pages/Shared/_FormFooter.cshtml @@ -44,11 +44,17 @@ }
-
- - - -
+ @if (Model.Kind != "C2") + + { + +
+ + + +
+ + }
@@ -79,13 +85,16 @@
- - - @if (Model.AllowsRemote) + @if (Model.AllowsRemote && Model.Kind != "C2") { + + } + else if (Model.Kind == "C2") + { + } else { @@ -93,7 +102,6 @@ } -
diff --git a/src/UDS.Net.Forms/Pages/UDS4/C2.cshtml b/src/UDS.Net.Forms/Pages/UDS4/C2.cshtml index e16860d6..78871703 100644 --- a/src/UDS.Net.Forms/Pages/UDS4/C2.cshtml +++ b/src/UDS.Net.Forms/Pages/UDS4/C2.cshtml @@ -2,1796 +2,86 @@ @model UDS.Net.Forms.Pages.UDS4.C2Model @{ Layout = "_LayoutForm"; + string rowCSS = "sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 sm:py-6"; }
+

+ INSTRUCTIONS: This form is to be completed by ADRC or clinic staff. For test administration and scoring, see , Form C2 or C2T. Any new participants who enroll in the UDS after the implementation of UDSv4 must be assessed with the new neuropsychological test battery (Form C2 or C2T). +

- INSTRUCTIONS: This form is to be completed by ADC or clinic staff. For test administration and scoring, see , Form C2. Any new participants who enroll in the UDS after the implementation of UDS3 must be assessed with the new neuropsychological test battery (Form C2).Any new participants who enroll in the UDS after the implementation of UDSv4 must be - assessed with the new neuropsychological test battery (Form C2 or C2T).
- KEY: If the participant cannot complete any of the following exams, please give the reason by entering one of the following codes: - 95 / 995 = Physical problem 96 / 996 = Cognitive/behavior problem 97 / 997 = Other problem 98 / 998 = Verbal refusal + KEY: If the participant cannot complete any of the following exams, please give the reason by entering one of the following codes: +

+

+ 95 / 995 = Physical problem + 96 / 996 = Cognitive/behavior problem + 97 / 997 = Other problem + 98 / 998 = Verbal refusal

-
-
- - @if (Model.Visit != null && (Model.C2.MODE == FormMode.InPerson)) - { -
-

- - Section 1 —Montreal Cognitive Assessment (MoCA) -

-
-
-
- -
-

- - -
-
-

- -
- -
- -
-
- -
- -
-

- - -
- -
- -
- -
-

- - -
-
-

- -
- -
- -
-
- -
- -
-

- - -
-
- -
- -
-

- - -
- -
-
-
- -

(Not corrected for education or visual/hearing impairment)

-

(Enter 88 if any of the following MoCA items were not administered: 1g –1l, 1n–1t, 1w–1bb)

-
-
-
- -
-

-
- -
- - -
- -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
-
- - -
-
- -
-

-
- -
-
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- - -
- - -
-
- -
-

-
- -
- -
-
-

- - Section 2 —Administration of the remainder of the battery -

-
-
- -
- -
- -
-

- - -
-
- -
- -
-

- - -
-
-

- -
- -
- -
-
- -
-
- -
-

- - Section 3 —Craft Story 21 Recall (Immediate) -

-
-
-
- -
-
- -

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 4a.)

-
-
-
- -
-

-
- -
- -
- -
-
- -
-

-
- -
- -
-
- -
-

- - Section 4 —Benson Complex Figure Copy -

-
- -
-
- -
-
- -

(If test not completed, enter reason code, 95–98)

-
-
-
- -
-

-
- -
-
-
-
-

- - Section 5 — Number Span Test: Forward -

-
-
- -
- -
-
- -

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 6a.)

-
-
-
- -
-

-
- -
-
- -
-
- -
-

-
- -
-
- -
- -
-

- - Section 6 — Number Span Test: Backward -

-
- -
-
- -
-
- -

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 7a.)

-
-
-
- -
-

-
- -
- -
- -
-
- -
-

-
- -
- -
-
- -
-

- - Section 7 — Category Fluency -

-
- -
-
- -
-
- -

(If test not completed, enter reason code, 95–98)

-
-
-
- -
-

-
- -
-
-
- -

(If test not completed, enter reason code, 95–98)

-
-
-
- -
-

-
- - -
-
-
-
-

- - Section 8 — Trail Making Test -

-
-
- -
- -
-
- -

(If test not completed, enter reason code, 995–998, and SKIP TO QUESTION 8b.).

-
-
-
- -
-

-
- - -
-
- -
-
- -
-
- -
-

-
- -
-
- -
-
- -
-

-
- -
-
- -
-
- -

(If test not completed, enter reason code, 995–998, and SKIP TO QUESTION 9a.).

-
-
-
- -
-

-
- - -
- -
-
- -
-
- -
-

-
- - -
-
- -
-
- -
-

-
- -
-
-
-
-
- - -
-
-
-

- - Section 9 — Benson Complex Figure Recall -

-
- -
- -
- -
-
- -

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 10a.

-
-
-
- -
-

-
- -
- - -
- -
-

- - -
-
- -
-
- -
-

- - Section 10 — Craft Story 21 Recall (Delayed) -

-
- -
- -
-
-
- -

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 11a.)

-
-
-
- -
-

-
- - -
- -
- -
-
- -
-

-
- - -
- -
- -
-
- -
-

-
- - -
- -
- -
-

- -
- -
- -
-
- -
-

- - Section 11 — Verbal Fluency: Phonemic Test -

-
-
- -
- -
-
- -

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 11d.)

-
-
-
- -
-

-
- -
- -
- -
-
- -
-

-
- - -
- -
- -
-
- -
-

-
- - -
- -
-
- -

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 12a.)

-
-
-
- -
-

-
- - -
- -
- -
-
- -
-

-
- - -
- -
- -
-
- -
-

-
- - -
- -
- -
-
- -
-

-
- -
- -
- -
-
- -
-

-
- - -
- -
- -
-
- -
-

-
- -
-
-
- -
-

- - -
-
-
- - -
-
-
-

- Section 12 — Rey Auditory Verbal Learning (Immediate) -

-
- -
- -
-

Total number of words correctly recalled and number of intrusions

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TrialTotal recall# of intrusions
Trial 1 -
- -
-
- - -
-
-

-
-

(If test was not completed, enter reason code, 95-98. SKIP TO QUESTION 16a.)

- -
-
- -
-
- - -
-
-

-
-
Trial 2 -
- -
-
- - -
-
-

-
- -
-
- -
-
- - -
-
-

-
-
Trial 3 -
- -
-
- - -
-
-

-
- -
-
- -
-
- - - -
-
-

-
-
Trial 4 -
- -
-
- - - -
-
-

-
- -
-
- -
-
- - - -
-
-

-
-
Trial 5 -
- -
-
- - - -
-
-

-
- -
-
- -
-
- - - -
-
-

-
-
List B -
- -
-
- - - -
-
-

-
- -
-
- -
-
- - - -
-
-

-
-
Trial 6 -
- -
-
- - - -
-
-

-
- -
-
- -
-
- - -
-
-

-
-
- -
- - -
- - -
-

- - Section 13 — Rey Auditory Verbal Learning (Delayed Recall and Recognition) -

- -
- -
- -
- -
-
- -

(If test not completed, enter reason code, 95-98, and SKIP TO QUESTION 16a.)

-
-
-
- -
-

- -
-
- -
- -
-
- -
-

- -
-
- -
- -
-
- -
-

- -
-
- -
- -
-

- - -
-
- -
- -
-
- -
-

- -
-
- -
- -
-
- -
-

- -
-
- -
- -
- -
-

- Section 14 — CERAD Verbal Learning (Immediate) -

-
-

- J4 Word List Memory Task: Total number of words correctly recalled and number of intrusions -

- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TrialTotal recallCan't read# of intrusions
Trial 1 -
- -
-
- -
-
-

-
- -

(If test was not completed, enter reason code, 95-98. SKIP TO QUESTION 16a.)

- -
-
- -
-
- -
-
-

-
- -
-
- -
-
- -
-
-

-
- -
Trial 2 -
- -
-
- -
-
-

-
- - -
-
- -
-
- -
-
-

-
- -
-
- -
-
- -
-
-

-
- -
Trial 3 -
- -
-
- -
-
-

-
- -
-
- -
-
- -
-
-

-
- -
-
- -
-
- -
-
-

-
- -
- -
- -
-

- - Section 15 — CERAD Verbal Learning (Delayed Recall and Recognition) -

-
- -
- -
-
- -
-
- -
-

-
- -
- -
-
- -

(If test not completed, enter reason code, 95-98, and SKIP TO QUESTION 16a.)

-
-
-
- -
-

-
- -
- -
- -
-
- -
-

-
- -
- -
-
- -

(If test not completed, enter reason code, 95-98, and SKIP TO QUESTION 16a.)

-
-
-
- -
-

-
- -
- -
- -
-
- -
-

-
- -
- - -
-
- -
-

- - Section 16 — Multilingual Naming Test (MINT) -

-
- -
- -
-
-
- -

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 17a)

-
-
-
- -
-

- -
-
- -
- -
-
- -
-

-
- -
- -
- -
-
- -
-

-
- -
- -
- -
-
- -
-

-
- -
- -
- -
-
- -
-

-
- -
- -
- -
-
- -
-

-
- -
- -
-
- - -
-

- - Section 17 — Overall appraisal -

-
- -
-
- -
- -
-
-

- - -
-
-
- -
- -
-
-

- - Section 18 — Validity of participant’s response -

-
-

- Please record your impression of whether hearing or other factors significantly influenced test results. It can be difficult to judge, but - it is helpful in adjudication and data analysis to know that such an influence may have been present. -

-
-
-
- -
-
-

- - -
-
-
- - -
-

- What makes this participant’s responses less valid? - -
-
- (Check all that apply) -

-
-
-
-
-
-
-
- -
- -
- @Html.CheckBox("C2.RESPHEAR", Model.C2.RESPHEAR, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) -
-
- -
-
-
-
-
-
-
-
- -
- -
- @Html.CheckBox("C2.RESPDIST", Model.C2.RESPDIST, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) -
-
- -
-
-
- -
-
-
-
-
- -
- -
- @Html.CheckBox("C2.RESPINTR", Model.C2.RESPINTR, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) -
-
- -
-
-
- -
-
-
-
-
- -
- -
- @Html.CheckBox("C2.RESPDISN", Model.C2.RESPDISN, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) -
-
- -
-
-
- -
-
-
-
-
- -
- -
- @Html.CheckBox("C2.RESPFATG", Model.C2.RESPFATG, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) -
-
- -
-
-
- -
-
-
-
-
- -
- -
- @Html.CheckBox("C2.RESPEMOT", Model.C2.RESPEMOT, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) -
-
- -
-
-
+
+ +
+
+
+ + + + + +
+
+ + + + +
-
-
-
-
-
- -
+ +
+ + @if (Model.Visit != null && (Model.C2.RMMODE == RemoteModality.Telephone)) -
- @Html.CheckBox("C2.RESPASST", Model.C2.RESPASST, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) -
-
- -
-
-
+ { + + } -
-
-
-
-
- -
+ else if (Model.Visit != null && (Model.C2.MODE == FormMode.InPerson) || (Model.C2.RMMODE == RemoteModality.Video)) -
- @Html.CheckBox("C2.RESPOTH", Model.C2.RESPOTH, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none", data_affects = "true", data_affects_toggle_targets = "[ \"C2.RESPOTHX\"]" }) -
-
- -
-
-
-

- -
- -
- -
-
-
- -
-
- } -
-
- + { + + } + +@section Scripts { + +} diff --git a/src/UDS.Net.Forms/Pages/UDS4/C2.cshtml.cs b/src/UDS.Net.Forms/Pages/UDS4/C2.cshtml.cs index 3978e587..45d520fb 100644 --- a/src/UDS.Net.Forms/Pages/UDS4/C2.cshtml.cs +++ b/src/UDS.Net.Forms/Pages/UDS4/C2.cshtml.cs @@ -290,6 +290,7 @@ public class C2Model : FormPageModel new UIDisableAttribute("C2.MOCAVIS"), new UIDisableAttribute("C2.MOCAHEAR"), new UIDisableAttribute("C2.MOCATOTS"), + new UIDisableAttribute("C2.MOCBTOTS"), new UIDisableAttribute("C2.MOCATRAI"), new UIDisableAttribute("C2.MOCACUBE"), new UIDisableAttribute("C2.MOCACLOC"), @@ -324,6 +325,7 @@ public class C2Model : FormPageModel new UIEnableAttribute("C2.MOCAVIS"), new UIEnableAttribute("C2.MOCAHEAR"), new UIEnableAttribute("C2.MOCATOTS"), + new UIEnableAttribute("C2.MOCBTOTS"), new UIEnableAttribute("C2.MOCATRAI"), new UIEnableAttribute("C2.MOCACUBE"), new UIEnableAttribute("C2.MOCACLOC"), @@ -405,6 +407,13 @@ public class C2Model : FormPageModel }; + public List VERBALTESTC2TListItems { get; set; } = new List + { + new RadioListItem("Rey AVLT (COMPLETE SECTIONS 6 & 13, SKIP SECTIONS 7 & 9)", "1"), + new RadioListItem("CERAD (COMPLETE SECTIONS 7 & 9 SKIP SECTIONS 6 & 13)", "2"), + + }; + public Dictionary VERBALTESTBehavior = new Dictionary { { "1", new UIBehavior { @@ -631,6 +640,29 @@ public async Task OnGetAsync(int? id) return Page(); } + public async Task OnGetC2Async(int? id) + { + await base.OnGetAsync(id); + + if (BaseForm != null) + { + C2 = (C2)BaseForm; // class library should always handle new instances + } + + return Partial("_C2", this); + } + + public async Task OnGetC2TAsync(int? id) + { + await base.OnGetAsync(id); + + if (BaseForm != null) + { + C2 = (C2)BaseForm; // class library should always handle new instances + } + + return Partial("_C2T", this); + } [ValidateAntiForgeryToken] public async Task OnPostAsync(int id) @@ -639,7 +671,7 @@ public async Task OnPostAsync(int id) Visit.Forms.Add(C2); // visit needs updated form as well - return await base.OnPostAsync(id); // checks for validation, etc. + return await base.OnPostAsync(id); // checks for validation, etc. } } } diff --git a/src/UDS.Net.Forms/Pages/UDS4/_C2.cshtml b/src/UDS.Net.Forms/Pages/UDS4/_C2.cshtml new file mode 100644 index 00000000..ad3e3a11 --- /dev/null +++ b/src/UDS.Net.Forms/Pages/UDS4/_C2.cshtml @@ -0,0 +1,1747 @@ +@model C2Model +@{ + string rowCSS = "sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 sm:py-6"; +} + + +
+ +
+

+ + Section 1 —Montreal Cognitive Assessment (MoCA) +

+
+
+
+ +
+

+ + +
+
+

+ +
+ +
+ +
+
+ +
+ +
+

+ + +
+
+ +
+ +
+

+ + +
+
+

+ +
+ +
+ +
+
+ +
+ +
+

+ + +
+
+ +
+ +
+

+ + +
+ +
+ +
+
+ +

(Not corrected for education or visual/hearing impairment)

+

(Enter 88 if any of the following MoCA items were not administered: 1g –1l, 1n–1t, 1w–1bb)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ +
+

+ + Section 2 —Administration of the remainder of the battery +

+
+ +
+
+ +
+ +
+

+ + +
+
+ +
+ +
+

+ + +
+
+

+ +
+ +
+ +
+
+ +
+
+ +
+

+ + Section 3 —Craft Story 21 Recall (Immediate) +

+
+ +
+
+ +
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 4a.)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+
+ +
+

+ + Section 4 —Benson Complex Figure Copy +

+
+ +
+
+ +
+
+ +

(If test not completed, enter reason code, 95–98)

+
+
+
+ +
+

+
+ +
+
+
+ +
+

+ + Section 5 — Number Span Test: Forward +

+
+ +
+
+ +
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 6a.)

+
+
+
+ +
+

+
+ +
+
+ +
+
+ +
+

+
+ +
+
+ +
+ +
+

+ + Section 6 — Number Span Test: Backward +

+
+ +
+
+ +
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 7a.)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+ +
+

+ + Section 7 — Category Fluency +

+
+ +
+
+ +
+
+ +

(If test not completed, enter reason code, 95–98)

+
+
+
+ +
+

+
+ +
+
+
+ +

(If test not completed, enter reason code, 95–98)

+
+ +
+
+ +
+

+
+ + +
+
+
+
+

+ + Section 8 — Trail Making Test +

+
+
+ +
+ +
+
+ +

(If test not completed, enter reason code, 995–998, and SKIP TO QUESTION 8b.).

+
+
+
+ +
+

+
+ + +
+
+ +
+
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+
+ +
+
+ +

(If test not completed, enter reason code, 995–998, and SKIP TO QUESTION 9a.).

+
+ +
+
+ +
+

+
+ + +
+ +
+
+ +
+
+ +
+

+
+ + +
+
+ +
+
+ +
+

+
+ +
+
+
+
+
+
+
+
+

+ + Section 9 — Benson Complex Figure Recall +

+
+ +
+ +
+ +
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 10a.

+
+
+
+ +
+

+
+ +
+ +
+ +
+

+ + +
+
+
+
+ +
+

+ + Section 10 — Craft Story 21 Recall (Delayed) +

+
+ +
+ +
+
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 11a.)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ + +
+ +
+ +
+
+ +
+

+
+ + +
+ +
+ +
+

+ +
+ +
+
+
+ +
+

+ + Section 11 — Verbal Fluency: Phonemic Test +

+
+
+ +
+ +
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 11d.)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ + +
+ +
+ +
+
+ +
+

+
+ + +
+ +
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 12a.)

+
+
+
+ +
+

+
+ + +
+ +
+ +
+
+ +
+

+
+ + +
+ +
+ +
+
+ +
+

+
+ + +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ + +
+ +
+ +
+
+ +
+

+
+ +
+
+
+ +
+

+ + +
+
+
+ +
+
+
+

+ Section 12 — Rey Auditory Verbal Learning (Immediate) +

+
+ +
+ +
+

Total number of words correctly recalled and number of intrusions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrialTotal recall# of intrusions
Trial 1 +
+ +
+
+ + +
+
+

+
+

(If test was not completed, enter reason code, 95-98. SKIP TO QUESTION 16a.)

+ +
+
+ +
+
+ + +
+
+

+
+
Trial 2 +
+ +
+
+ + +
+
+

+
+ +
+
+ +
+
+ + +
+
+

+
+
Trial 3 +
+ +
+
+ + +
+
+

+
+ +
+
+ +
+
+ + + +
+
+

+
+
Trial 4 +
+ +
+
+ + + +
+
+

+
+ +
+
+ +
+
+ + + +
+
+

+
+
Trial 5 +
+ +
+
+ + + +
+
+

+
+ +
+
+ +
+
+ + + +
+
+

+
+
List B +
+ +
+
+ + + +
+
+

+
+ +
+
+ +
+
+ + + +
+
+

+
+
Trial 6 +
+ +
+
+ + + +
+
+

+
+ +
+
+ +
+
+ + +
+
+

+
+
+
+
+ +
+

+ + Section 13 — Rey Auditory Verbal Learning (Delayed Recall and Recognition) +

+ +
+ +
+
+ +
+
+ +

(If test not completed, enter reason code, 95-98, and SKIP TO QUESTION 16a.)

+
+
+
+ +
+

+ +
+
+ +
+ +
+
+ +
+

+ +
+
+ +
+ +
+
+ +
+

+ +
+
+ +
+ +
+

+ + +
+
+ +
+ +
+
+ +
+

+ +
+
+ +
+ +
+
+ +
+

+ +
+
+ +
+
+ +
+

+ Section 14 — CERAD Verbal Learning (Immediate) +

+
+ +

+ J4 Word List Memory Task: Total number of words correctly recalled and number of intrusions +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrialTotal recallCan't read# of intrusions
Trial 1 +
+ +
+
+ +
+
+

+
+ +

(If test was not completed, enter reason code, 95-98. SKIP TO QUESTION 16a.)

+ +
+
+ +
+
+ +
+
+

+
+ +
+
+ +
+
+ +
+
+

+
+ +
Trial 2 +
+ +
+
+ +
+
+

+
+ + +
+
+ +
+
+ +
+
+

+
+ +
+
+ +
+
+ +
+
+

+
+ +
Trial 3 +
+ +
+
+ +
+
+

+
+ +
+
+ +
+
+ +
+
+

+
+ +
+
+ +
+
+ +
+
+

+
+ +
+
+ +
+

+ + Section 15 — CERAD Verbal Learning (Delayed Recall and Recognition) +

+
+ +
+
+
+ +
+
+ +
+

+
+ +
+ +
+
+ +

(If test not completed, enter reason code, 95-98, and SKIP TO QUESTION 16a.)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+
+ +

(If test not completed, enter reason code, 95-98, and SKIP TO QUESTION 16a.)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+
+ +
+

+ + Section 16 — Multilingual Naming Test (MINT) +

+
+ +
+
+
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 17a)

+
+
+
+ +
+

+ +
+
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+
+
+ +
+

+ + Section 17 — Overall appraisal +

+
+ +
+
+ +
+ +
+
+

+ + +
+
+
+
+ +
+
+

+ + Section 18 — Validity of participant’s response +

+
+

+ Please record your impression of whether hearing or other factors significantly influenced test results. It can be difficult to judge, but + it is helpful in adjudication and data analysis to know that such an influence may have been present. +

+
+
+
+ +
+
+

+ + +
+
+
+ +
+

+ What makes this participant’s responses less valid? + +
+
+ (Check all that apply) +

+
+
+
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPHEAR", Model.C2.RESPHEAR, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPDIST", Model.C2.RESPDIST, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPINTR", Model.C2.RESPINTR, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPDISN", Model.C2.RESPDISN, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPFATG", Model.C2.RESPFATG, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPEMOT", Model.C2.RESPEMOT, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPASST", Model.C2.RESPASST, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPOTH", Model.C2.RESPOTH, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none", data_affects = "true", data_affects_toggle_targets = "[ \"C2.RESPOTHX\"]" }) +
+
+ +
+
+
+

+ +
+ +
+ +
+
+
+ +
+
+
+ + +
\ No newline at end of file diff --git a/src/UDS.Net.Forms/Pages/UDS4/_C2T.cshtml b/src/UDS.Net.Forms/Pages/UDS4/_C2T.cshtml new file mode 100644 index 00000000..48fdb814 --- /dev/null +++ b/src/UDS.Net.Forms/Pages/UDS4/_C2T.cshtml @@ -0,0 +1,1483 @@ +@model C2Model +@{ + string rowCSS = "sm:grid sm:grid-cols-3 sm:items-start sm:gap-4 sm:py-6"; +} + + +
+
+

+ + Section 1 —Montreal Cognitive Assessment (MoCA) +

+
+
+
+ +
+

+ + +
+
+

+ +
+ +
+ +
+
+ +
+ +
+

+ + +
+
+

+ +
+ +
+ +
+
+ +
+ +
+

+ + +
+ +
+
+
+ +

(Not corrected for education or visual/hearing impairment)

+

(Enter 88 if any of the following MoCA items were not administered: 1e –1k, 1n–1s)

+
+
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+
+ + +
+
+ +
+

+
+ +
+
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ + +
+
+ +
+

+
+ +
+
+
+

+ + Section 2 —Administration of the remainder of the battery +

+
+
+ +
+
+ +
+

+ + +
+
+

+ +
+ +
+ +
+
+
+
+ +
+

+ + Section 3 —Craft Story 21 Recall (Immediate) +

+
+
+
+ +
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 4a.)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+
+
+ +
+

+ + Section 4 — Number Span Test: Forward +

+
+
+
+ +
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 5a.)

+
+
+
+ +
+

+
+ +
+
+ +
+
+ +
+

+
+ +
+
+
+ +
+

+ + Section 5 — Number Span Test: Backward +

+
+ +
+
+
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 6.)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+
+ +
+

+ + +
+
+
+
+
+ +
+

+ Section 6 — Rey Auditory Verbal Learning (Immediate) +

+
+ +
+
+ +

Total number of words correctly recalled and number of intrusions

+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrialTotal recall# of intrusions
Trial 1 +
+ +
+
+ + +
+
+

+
+

(If test was not completed, enter reason code, 95-98. SKIP TO QUESTION 8a.)

+ +
+
+ +
+
+ + +
+
+

+
+
Trial 2 +
+ +
+
+ + +
+
+

+
+ +
+
+ +
+
+ + +
+
+

+
+
Trial 3 +
+ +
+
+ + +
+
+

+
+ +
+
+ +
+
+ + + +
+
+

+
+
Trial 4 +
+ +
+
+ + + +
+
+

+
+ +
+
+ +
+
+ + + +
+
+

+
+
Trial 5 +
+ +
+
+ + + +
+
+

+
+ +
+
+ +
+
+ + + +
+
+

+
+
List B +
+ +
+
+ + + +
+
+

+
+ +
+
+ +
+
+ + + +
+
+

+
+
Trial 6 +
+ +
+
+ + + +
+
+

+
+ +
+
+ +
+
+ + +
+
+

+
+
+
+
+
+

+ Section 7 — CERAD Verbal Learning (Immediate) +

+
+

+ J4 Word List Memory Task: Total number of words correctly recalled and number of intrusions +

+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + +
TrialTotal recall# of intrusions
Trial 1 +
+ +
+
+ +
+
+

+
+ +

(If test was not completed, enter reason code, 95-98. SKIP TO QUESTION 8a.)

+ +
+
+ +
+
+ +
+
+

+
+ +
Trial 2 +
+ +
+
+ +
+
+

+
+ + +
+
+ +
+
+ +
+
+

+
+ +
Trial 3 +
+ +
+
+ +
+
+

+
+ +
+
+ +
+
+ +
+
+

+
+ +
+
+
+
+
+
+
+

+ + Section 8 — Catagory Fluency +

+
+
+
+
+
+ +

(If test not completed, enter reason code, 95–98)

+
+
+
+ +
+

+
+ +
+
+
+ +

(If test not completed, enter reason code, 95–98)

+
+
+
+ +
+

+
+ + +
+
+
+ +
+

+ + Section 9 — CERAD Verbal Learning (Delayed Recall and Recognition) +

+
+ +
+
+
+ +
+
+ +
+

+
+ +
+ +
+
+ +

(If test not completed, enter reason code, 95-98, and SKIP TO QUESTION 9d.)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+
+ +

(If test not completed, enter reason code, 95-98, and SKIP TO QUESTION 10a.)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+
+ +
+

+ + Section 10 — Oral Trail Making Test (Optional) @* TODO Add Properties to model & Map*@ +

+
+
+
+
+
+
+ +

+ (If test not completed, enter reason code, 995–998. If test was skipped because optional, enter 888. SKIP + TO QUESTION 10b.) +

+
+
+
+ +
+

+
+ +
+ +
+
+ +
+
+
+ +
+

+
+ + +
+
+
+ +
+
+
+ +
+

+
+ +
+
+
+ +
+
+
+ +

+ (If test not completed, enter reason code, 995–998. If test was skipped because optional, enter 888. SKIP + TO QUESTION 11a.) +

+
+
+
+ +
+

+
+ +
+ +
+
+ +
+
+
+ +
+

+
+ +
+ +
+
+ +
+
+
+ +
+

+
+ +
+
+
+ +
+

+ Section 11 — Craft Story 21 Recall (Delayed) +

+
+ +
+ +
+
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 12a.)

+
+
+
+ +
+

+
+ + +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ + +
+ +
+ +
+

+ +
+ +
+
+
+ +
+

+ + Section 12 — Verbal Fluency: Phonemic Test +

+
+ +
+
+ +
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 12d.)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+
+ +

(If test not completed, enter reason code, 95–98, and SKIP TO QUESTION 13a.)

+
+
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+ +
+ +
+
+ +
+

+
+ +
+
+
+ +
+

+ Section 13 — Rey Auditory Verbal Learning (Delayed Recall and Recognition) +

+
+ +
+ +
+
+
+ +

(If test not completed, enter reason code, 95-98, and SKIP TO QUESTION 14a.)

+
+
+
+ +
+

+ +
+
+ +
+ +
+
+ +
+

+ +
+
+ +
+ +
+
+ +
+

+ +
+
+ +
+ +
+
+ +
+

+ +
+
+ +
+ +
+
+ +
+

+ +
+
+
+
+ +
+

+ + Section 14 — Verbal Naming Test (Optional) @* TODO Add Properties To Model *@ +

+
+ +
+
+
+
+ +

(If test was not completed, enter reason code, 95-98. If test was skipped because optional, enter 88.)

+
+
+
+ +
+

+ +
+
+
+
+ +

+ (If test was not completed, enter reason code, 95-98. If test was skipped because optional or if no cues were + given, enter 88) +

+
+
+
+ +
+

+ +
+
+
+
+ +
+

+ + Section 15 — Overall appraisal +

+
+ +
+
+
+ +
+
+

+ + +
+
+
+
+
+ + +
+

+ + Section 16 — Validity of participant's responses +

+
+ +
+
+

+ Please record your impression of whether hearing or other factors significantly influenced test results. It can be difficult to judge, but + it is helpful in adjudication and data analysis to know that such an influence may have been present. +

+
+
+
+ +
+
+

+ + +
+
+
+ +
+

+ What makes this participant’s responses less valid? +
+
+ (Check all that apply) +

+
+
+
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPHEAR", Model.C2.RESPHEAR, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPDIST", Model.C2.RESPDIST, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPINTR", Model.C2.RESPINTR, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPDISN", Model.C2.RESPDISN, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPFATG", Model.C2.RESPFATG, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPEMOT", Model.C2.RESPEMOT, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPASST", Model.C2.RESPASST, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none" }) +
+
+ +
+
+
+ +
+
+
+
+
+ +
+ +
+ @Html.CheckBox("C2.RESPOTH", Model.C2.RESPOTH, new { @class = "h-4 w-4 rounded border-gray-300 text-indigo-600 focus:ring-indigo-600 disabled:bg-slate-50 disabled:text-slate-500 disabled:border-slate-200 disabled:shadow-none", data_affects = "true", data_affects_toggle_targets = "[ \"C2.RESPOTHX\"]" }) +
+
+ +
+
+
+

+ +
+ +
+ +
+
+
+ +
+
+
+ +
+
+ +
\ No newline at end of file diff --git a/src/UDS.Net.Forms/UDS.Net.Forms.csproj b/src/UDS.Net.Forms/UDS.Net.Forms.csproj index 715705bd..2c3a3368 100644 --- a/src/UDS.Net.Forms/UDS.Net.Forms.csproj +++ b/src/UDS.Net.Forms/UDS.Net.Forms.csproj @@ -6,13 +6,13 @@ enable true UDS.Net.Forms - 4.1.3 + 4.2.0 Sanders-Brown Center on Aging UDS Forms razor class library UK-SBCoA Razor class library for rendering UDS forms https://github.com/UK-SBCoA/uniform-data-set-dotnet-web - 4.1.3 + 4.2.0 @@ -25,8 +25,8 @@ - - + + runtime; build; native; contentfiles; analyzers; buildtransitive diff --git a/src/UDS.Net.Forms/Views/Shared/_C2Validation.cshtml b/src/UDS.Net.Forms/Views/Shared/_C2Validation.cshtml new file mode 100644 index 00000000..c41eaff3 --- /dev/null +++ b/src/UDS.Net.Forms/Views/Shared/_C2Validation.cshtml @@ -0,0 +1,19 @@ +@using UDS.Net.Forms.Pages.UDS4; +@model C2Model + + + + \ No newline at end of file diff --git a/src/UDS.Net.Forms/Views/Shared/_LayoutHtmlHeadPartial.cshtml b/src/UDS.Net.Forms/Views/Shared/_LayoutHtmlHeadPartial.cshtml index 21cd4443..5a484c78 100644 --- a/src/UDS.Net.Forms/Views/Shared/_LayoutHtmlHeadPartial.cshtml +++ b/src/UDS.Net.Forms/Views/Shared/_LayoutHtmlHeadPartial.cshtml @@ -12,4 +12,4 @@ - \ No newline at end of file + diff --git a/src/UDS.Net.Forms/wwwroot/js/C2.js b/src/UDS.Net.Forms/wwwroot/js/C2.js new file mode 100644 index 00000000..f5cb381f --- /dev/null +++ b/src/UDS.Net.Forms/wwwroot/js/C2.js @@ -0,0 +1,20 @@ + + +//handles the dropdowns to determine whether C2 or C2T is used + +$(document).ready(function () { + const modality = document.getElementById("modalityselect"); + const inputElement = document.getElementById("remote"); + + function handleDropdownChange() { + if (modality.value === "2") { + inputElement.disabled = false; + } else { + inputElement.disabled = true; + inputElement.value = ""; + } + } + handleDropdownChange(); + + modality.addEventListener("change", handleDropdownChange); +}); diff --git a/src/UDS.Net.Forms/wwwroot/js/js_controllers/selectendpoint_controller.js b/src/UDS.Net.Forms/wwwroot/js/js_controllers/selectendpoint_controller.js new file mode 100644 index 00000000..a03dd9b0 --- /dev/null +++ b/src/UDS.Net.Forms/wwwroot/js/js_controllers/selectendpoint_controller.js @@ -0,0 +1,42 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["dropdown"] + static values = { visitId: Number } + + remoteModeDropdown(event) { + const dropdown = this.dropdownTarget; + const dropdownValue = dropdown.value; + const visitId = this.visitIdValue; + + const turboFrameId = dropdown.dataset.turboframe; + const turboFrame = document.querySelector(`turbo-frame#${turboFrameId}`); + + const remoteEndPoint = dropdown.dataset.remoteEndPoint; + const inPersonEndPoint = dropdown.dataset.inPersonEndPoint; + + if (visitId) { + if (dropdownValue == 1) { + turboFrame.src = `${remoteEndPoint}`; + } else { + turboFrame.src = `${inPersonEndPoint}`; + } + } + } + modeDropdown(event) { + const dropdown = this.dropdownTarget; + const dropdownValue = dropdown.value; + const visitId = this.visitIdValue; + + const turboFrameId = dropdown.dataset.turboframe; + const turboFrame = document.querySelector(`turbo-frame#${turboFrameId}`); + + const inPersonEndPoint = dropdown.dataset.inPersonEndPoint; + + if (visitId) { + if (dropdownValue == 1) { + turboFrame.src = `${inPersonEndPoint}`; + } + } + } +} \ No newline at end of file diff --git a/src/UDS.Net.Forms/wwwroot/js/stimulus_controllers.js b/src/UDS.Net.Forms/wwwroot/js/stimulus_controllers.js index 36261328..a07696d0 100644 --- a/src/UDS.Net.Forms/wwwroot/js/stimulus_controllers.js +++ b/src/UDS.Net.Forms/wwwroot/js/stimulus_controllers.js @@ -4,6 +4,7 @@ import Dropdown from "./js_controllers/dropdown_controller.js" import MobileMenu from "./js_controllers/mobilemenu_controller.js" import FancyCheckboxes from "./js_controllers/fancycheckboxes_controller.js" import CheckboxDisable from "./js_controllers/checkboxDisable_controller.js" +import selectendpoint_controller from "./js_controllers/selectendpoint_controller.js" window.Stimulus = Application.start() @@ -12,3 +13,4 @@ Stimulus.register("dropdown", Dropdown) Stimulus.register("mobilemenu", MobileMenu) Stimulus.register("fancycheckboxes", FancyCheckboxes) Stimulus.register("checkboxDisable", CheckboxDisable) +Stimulus.register("selectendpoint", selectendpoint_controller) diff --git a/src/UDS.Net.Services.Test/UDS.Net.Services.Test.csproj b/src/UDS.Net.Services.Test/UDS.Net.Services.Test.csproj index 9f63eccd..1e52a30e 100644 --- a/src/UDS.Net.Services.Test/UDS.Net.Services.Test.csproj +++ b/src/UDS.Net.Services.Test/UDS.Net.Services.Test.csproj @@ -7,7 +7,7 @@ false true - 4.1.3 + 4.2.0 diff --git a/src/UDS.Net.Services/DomainModels/Forms/C2FormFields.cs b/src/UDS.Net.Services/DomainModels/Forms/C2FormFields.cs index 7c21894e..2f4627f0 100644 --- a/src/UDS.Net.Services/DomainModels/Forms/C2FormFields.cs +++ b/src/UDS.Net.Services/DomainModels/Forms/C2FormFields.cs @@ -19,6 +19,7 @@ public class C2FormFields : IFormFields public int? MOCATRAI { get; set; } public int? MOCACUBE { get; set; } public int? MOCACLOC { get; set; } + public int? MOCBTOTS { get; set; } public int? MOCACLON { get; set; } public int? MOCACLOH { get; set; } public int? MOCANAMI { get; set; } @@ -64,6 +65,7 @@ public class C2FormFields : IFormFields public int? DIGBACLS { get; set; } public int? OTRAILA { get; set; } public int? OTRLARR { get; set; } + public int? OTRALI { get; set; } public int? OTRLALI { get; set; } public int? OTRAILB { get; set; } public int? OTRLBRR { get; set; } @@ -180,6 +182,7 @@ public C2FormFields(FormDto dto) MOCAVIS = c2Dto.MOCAVIS; MOCAHEAR = c2Dto.MOCAHEAR; MOCATOTS = c2Dto.MOCATOTS; + MOCBTOTS = c2Dto.MOCBTOTS; MOCATRAI = c2Dto.MOCATRAI; MOCACUBE = c2Dto.MOCACUBE; MOCACLOC = c2Dto.MOCACLOC; @@ -263,6 +266,8 @@ public C2FormFields(FormDto dto) REYMETHOD = c2Dto.REYMETHOD; REYTCOR = c2Dto.REYTCOR; REYFPOS = c2Dto.REYFPOS; + VNTTOTW = c2Dto.VNTTOTW; + VNTPCNC = c2Dto.VNTPCNC; CERAD1REC = c2Dto.CERAD1REC; CERAD1READ = c2Dto.CERAD1READ; CERAD1INT = c2Dto.CERAD1INT; @@ -277,6 +282,12 @@ public C2FormFields(FormDto dto) CERADJ6INT = c2Dto.CERADJ6INT; CERADJ7YES = c2Dto.CERADJ7YES; CERADJ7NO = c2Dto.CERADJ7NO; + OTRAILA = c2Dto.OTRAILA; + OTRLARR = c2Dto.OTRLARR; + OTRLALI = c2Dto.OTRLALI; + OTRAILB = c2Dto.OTRAILB; + OTRLBRR = c2Dto.OTRLBRR; + OTRLBLI = c2Dto.OTRLBLI; RESPVAL = c2Dto.RESPVAL; RESPHEAR = c2Dto.RESPHEAR; RESPDIST = c2Dto.RESPDIST; diff --git a/src/UDS.Net.Services/Extensions/DomainToDtoMapper.cs b/src/UDS.Net.Services/Extensions/DomainToDtoMapper.cs index 21d84e68..93f28923 100644 --- a/src/UDS.Net.Services/Extensions/DomainToDtoMapper.cs +++ b/src/UDS.Net.Services/Extensions/DomainToDtoMapper.cs @@ -1297,6 +1297,7 @@ public static C2Dto ToDto(this C2FormFields fields) MOCAVIS = fields.MOCAVIS, MOCAHEAR = fields.MOCAHEAR, MOCATOTS = fields.MOCATOTS, + MOCBTOTS = fields.MOCBTOTS, MOCATRAI = fields.MOCATRAI, MOCACUBE = fields.MOCACUBE, MOCACLOC = fields.MOCACLOC, @@ -1380,6 +1381,8 @@ public static C2Dto ToDto(this C2FormFields fields) REYMETHOD = fields.REYMETHOD, REYTCOR = fields.REYTCOR, REYFPOS = fields.REYFPOS, + VNTTOTW = fields.VNTTOTW, + VNTPCNC = fields.VNTPCNC, CERAD1REC = fields.CERAD1REC, CERAD1READ = fields.CERAD1READ, CERAD1INT = fields.CERAD1INT, @@ -1394,6 +1397,12 @@ public static C2Dto ToDto(this C2FormFields fields) CERADJ6INT = fields.CERADJ6INT, CERADJ7YES = fields.CERADJ7YES, CERADJ7NO = fields.CERADJ7NO, + OTRAILA = fields.OTRAILA, + OTRLARR = fields.OTRLARR, + OTRLALI = fields.OTRLALI, + OTRAILB = fields.OTRAILB, + OTRLBRR = fields.OTRLBRR, + OTRLBLI = fields.OTRLBLI, RESPVAL = fields.RESPVAL, RESPHEAR = fields.RESPHEAR, RESPDIST = fields.RESPDIST, diff --git a/src/UDS.Net.Services/UDS.Net.Services.csproj b/src/UDS.Net.Services/UDS.Net.Services.csproj index 1ea52999..5c388a2a 100644 --- a/src/UDS.Net.Services/UDS.Net.Services.csproj +++ b/src/UDS.Net.Services/UDS.Net.Services.csproj @@ -4,15 +4,15 @@ netstandard2.1 Library UDS.Net.Services - 4.1.3 + 4.2.0 Sanders-Brown Center on Aging Service contracts for implmenting your own back-end with MVC web app UK-SBCoA Service contracts required by MVC web app https://github.com/UK-SBCoA/uniform-data-set-dotnet-web - 4.1.3 + 4.2.0 - + \ No newline at end of file diff --git a/src/UDS.Net.Web.MVC.Services/UDS.Net.Web.MVC.Services.csproj b/src/UDS.Net.Web.MVC.Services/UDS.Net.Web.MVC.Services.csproj index 6f23d775..c05df91b 100644 --- a/src/UDS.Net.Web.MVC.Services/UDS.Net.Web.MVC.Services.csproj +++ b/src/UDS.Net.Web.MVC.Services/UDS.Net.Web.MVC.Services.csproj @@ -4,18 +4,18 @@ netstandard2.1 Library UDS.Net.MVC.Services - 4.1.3 + 4.2.0 Sanders-Brown Center on Aging Implemented service layer for using MVC front-end with API back-end UK-SBCoA Implemented service contract https://github.com/UK-SBCoA/uniform-data-set-dotnet-web - 4.1.3 + 4.2.0 - - + + diff --git a/src/UDS.Net.Web.MVC/UDS.Net.Web.MVC.csproj b/src/UDS.Net.Web.MVC/UDS.Net.Web.MVC.csproj index a5e43865..d4065fbb 100644 --- a/src/UDS.Net.Web.MVC/UDS.Net.Web.MVC.csproj +++ b/src/UDS.Net.Web.MVC/UDS.Net.Web.MVC.csproj @@ -6,7 +6,7 @@ enable aspnet-UDS.Net.Web.MVC-F92C0881-61B6-4292-8635-0004DE84CFE6 ../docker-compose.dcproj - 4.1.3 + 4.2.0 @@ -20,8 +20,8 @@ all - - + +