@using System.Text Item Identifier: @Value @if (_identifierError) { All identifier fields must be filled in. } @for (int index = 0; index < IdentifierFields.Count; index++) { // You must create a local variable inside the loop for binding to work correctly. var field = IdentifierFields[index]; @if (index < IdentifierFields.Count - 1) { @FieldSeparator } } @using OpenArchival.DataAccess; @inject IArchiveCategoryProvider CategoryProvider; @code { [Parameter] public required string FieldSeparator { get; set; } = "-"; private List _identifierFields = new(); [Parameter] public required List IdentifierFields { get => _identifierFields; set => _identifierFields = value ?? new(); } [Parameter] public EventCallback ValueChanged { get; set; } private ArchiveCategory _verifyFormatCategory; public ArchiveCategory? VerifyFormatCategory { get { return _verifyFormatCategory; } set { if (value is not null) { _identifierFields.Clear(); _verifyFormatCategory = value; foreach (var field in value.FieldNames) { _identifierFields.Add(new IdentifierFieldValidationModel() {Name=field, Value=""}); } } } } public bool IsValid { get; set; } = false; // Computed property that builds the final string public string Value => string.Join(FieldSeparator, IdentifierFields.Select(f => f.Value).Where(v => !string.IsNullOrEmpty(v))); private bool _identifierError = false; /// /// This runs when parameters are first set, ensuring the initial state is correct. /// protected override void OnParametersSet() { ValidateFields(); StateHasChanged(); } /// /// This runs after the user types into a field. /// private async Task OnInputChanged() { ValidateFields(); await ValueChanged.InvokeAsync(this.Value); } /// /// Reusable method to check the validity of the identifier fields. /// private void ValidateFields() { // Set to true if ANY field is empty or null. _identifierError = IdentifierFields.Any(f => string.IsNullOrEmpty(f.Value)); IsValid = !_identifierError; } }