Required Validator Not Working in Blazor In Line Edit Data Grid

I am trying to implement a Required Validator on a RadzenDataGrid with In-line edit. However, my app is behaving as if the validator isn't there.

This is my code:

<RadzenDataGrid @ref="CdAssignmentTypeGrid" AllowFiltering="true" AllowPaging="true" PageSize="20" AllowSorting="true"
EditMode="DataGridEditMode.Single" AllowColumnResize="true"
Data="@CdAssignmentType_Collection" TItem="CdAssignmentType" RowUpdate="@OnUpdateRow" RowCreate="@OnCreateRow">



<RadzenTextBox @bind-Value="CdAssignmentType_Singleton.Name"
Name="Name" Style="width:100%; display: block"/>


























I have seen the note in documentation that a RadzenTemplateForm is required for validators, but do not see that in the published example and do not believe it makes sense for an In-Line Edit Grid.

Any guidance is appreciated.

Thanks.

Struggling to copy my code in-line. I hope this will work:

ValidationSnippet.zip (1.1 KB)

The provided code is incomplete - it lacks the event handlers. You can format your code according to the forum FAQ - use Markdown code snippets.

Also check our online demo which shows correctly working validation (ShipName is required).

Thank you Korchev. I have been trying to follow the online demo and assume I am missing something silly. Here is my code:

'''<RadzenDataGrid @ref="CdAssignmentTypeGrid" AllowFiltering="true" AllowPaging="true" PageSize="20" AllowSorting="true"
EditMode="DataGridEditMode.Single" AllowColumnResize="true"
Data="@CdAssignmentType_Collection" TItem="CdAssignmentType" RowUpdate="@OnUpdateRow" RowCreate="@OnCreateRow">



<RadzenTextBox @bind-Value="CdAssignmentType_Singleton.Name"
Name="Name" Style="width:100%; display: block"/>


























@code {

RadzenDataGrid<CdAssignmentType> CdAssignmentTypeGrid;
IList<CdAssignmentType> CdAssignmentType_Collection = new List<CdAssignmentType>();


//Lookup Values

protected override async Task OnInitializedAsync()
{
    await RequeryData(true);


}
async Task RequeryData(bool forceRefresh)
{


    //Step 1:  Prepare Data Request
    DataRequestParameters DataRqstPmtr = new DataRequestParameters()
    {
    BaseEntity = enumDataSource.CdAssignmentType,
    ProductId = Guid.Empty,
    LimitToProduct = false
};




    //Step 2:  Call WebApi Controller
    var PostResult = await client.PostAsJsonAsync("api/genericdatarequest", DataRqstPmtr);
    var resultString = await PostResult.Content.ReadAsStringAsync();

    CdAssignmentType_Collection = JsonSerializer.Deserialize<IList<CdAssignmentType>>(resultString, JsonHelper.SerializationOptions);

    if (forceRefresh)
    {
        await InvokeAsync(StateHasChanged);
    }
}


void InsertRow()
{
    CdAssignmentTypeGrid.InsertRow(new CdAssignmentType());

}

void EditRow(CdAssignmentType CdAssignmentType_Singleton)
{
CdAssignmentTypeGrid.EditRow(CdAssignmentType_Singleton);
}

async Task OnUpdateRow(CdAssignmentType CdAssignmentType_Singleton)
{
await client.PutAsJsonAsync("api/toolset", CdAssignmentType_Singleton);

NotificationService.Notify(new NotificationMessage()
    {
    Severity = NotificationSeverity.Success
    ,Summary = "Successful Save"
    ,Detail = CdAssignmentType_Singleton.Name + " was saved successfully."
    ,Duration = 4000
}
);

}

async Task SaveRow(CdAssignmentType CdAssignmentType_Singleton)
{

await client.PutAsJsonAsync("api/CdAssignmentType", CdAssignmentType_Singleton, JsonHelper.SerializationOptions);

NotificationService.Notify(new NotificationMessage()
    {
    Severity = NotificationSeverity.Success
    ,Summary = "Successful Save"
    ,Detail = CdAssignmentType_Singleton.Name + " was saved successfully."
    ,Duration = 4000
}
);

CdAssignmentTypeGrid.CancelEditRow(CdAssignmentType_Singleton);

await RequeryData(true);

}

async Task CancelEdit(CdAssignmentType CdAssignmentType_Singleton)
{
CdAssignmentTypeGrid.CancelEditRow(CdAssignmentType_Singleton);
await RequeryData(true);
}

async Task DeleteRow(CdAssignmentType CdAssignmentType_Singleton)
{
if (CdAssignmentType_Collection.Contains(CdAssignmentType_Singleton))
{

    string ConfirmHeader = "Confirm Delete";
    string ConfirmText = "Clicking 'Delete' will Remove " + CdAssignmentType_Singleton.Name;
    
    
    ConfirmOptions _ConfirmOptions = new ConfirmOptions()
        {
        OkButtonText = "Delete",
        CancelButtonText = "Cancel",
        Width = "800px"
    };
    
    var confirmResult = await DialogService.Confirm(
    ConfirmText, ConfirmHeader, _ConfirmOptions);
    
    if ((bool)confirmResult)
        {
        await client.DeleteAsync($"api/CdAssignmentType/{CdAssignmentType_Singleton.Id}");
        
        NotificationService.Notify(new NotificationMessage()
            {
            Severity = NotificationSeverity.Success
            ,Summary = "Successful Delete"
            ,Detail = CdAssignmentType_Singleton.Name + " was successfully deleted."
            ,Duration = 4000
        }
        );
        
        await RequeryData(true);
    }
}

}

async Task OnCreateRow(CdAssignmentType CdAssignmentType_Singleton)
{
await client.PostAsJsonAsync("api/CdAssignmentType", CdAssignmentType_Singleton);
}

}
'''

Your code is not formatted properly - use back ticks (`) instead of apostrophe (').

Thank you again:

<RadzenDataGrid @ref="CdAssignmentTypeGrid" AllowFiltering="true" AllowPaging="true" PageSize="20" AllowSorting="true"
    EditMode="DataGridEditMode.Single" AllowColumnResize="true"
    Data="@CdAssignmentType_Collection" TItem="CdAssignmentType" RowUpdate="@OnUpdateRow" RowCreate="@OnCreateRow">
    <Columns>
        <RadzenDataGridColumn TItem="CdAssignmentType" Property="Name" Title="Name" 
            Visible="true">
            <EditTemplate  Context="CdAssignmentType_Singleton">
                <RadzenTextBox @bind-Value="CdAssignmentType_Singleton.Name"
                    Name="Name" Style="width:100%; display: block"/>
                <RadzenRequiredValidator Text="Name is required" Component="Name" Popup="true" />
            </EditTemplate>
        </RadzenDataGridColumn>
         <RadzenDataGridColumn TItem="CdAssignmentType" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="100px">
            <Template Context="CdAssignmentType_Singleton">
                <RadzenButton Icon="edit" Size="ButtonSize.Small" Click="@(args => EditRow(CdAssignmentType_Singleton))">
                </RadzenButton>
            </Template>
            <EditTemplate Context="CdAssignmentType_Singleton">
                <RadzenButton ButtonType="ButtonType.Submit" Icon="save" Size="ButtonSize.Small" Click="@((args) => SaveRow(CdAssignmentType_Singleton))">
                </RadzenButton>
                <RadzenButton Icon="cancel" Size="ButtonSize.Small" ButtonStyle="ButtonStyle.Secondary" Click="@((args) => CancelEdit(CdAssignmentType_Singleton))">
                </RadzenButton>
            </EditTemplate>
        </RadzenDataGridColumn>
        <RadzenDataGridColumn TItem="CdAssignmentType" Filterable="false" Sortable="false" TextAlign="TextAlign.Center" Width="70px">
            <Template Context="CdAssignmentType_Singleton">
                <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="close" Size="ButtonSize.Small" Click="@(args => DeleteRow(CdAssignmentType_Singleton))">
                </RadzenButton>
            </Template>
            <EditTemplate Context="CdAssignmentType_Singleton">
                <RadzenButton ButtonStyle="ButtonStyle.Danger" Icon="close" Size="ButtonSize.Small" Click="@(args => DeleteRow(CdAssignmentType_Singleton))">
                </RadzenButton>
            </EditTemplate>
        </RadzenDataGridColumn>
    </Columns>
</RadzenDataGrid>

@code {



    RadzenDataGrid<CdAssignmentType> CdAssignmentTypeGrid;
    IList<CdAssignmentType> CdAssignmentType_Collection = new List<CdAssignmentType>();


    //Lookup Values

    protected override async Task OnInitializedAsync()
    {
        await RequeryData(true);


    }
    async Task RequeryData(bool forceRefresh)
    {


        //Step 1:  Prepare Data Request
        DataRequestParameters DataRqstPmtr = new DataRequestParameters()
        {
        BaseEntity = enumDataSource.CdAssignmentType,
        ProductId = Guid.Empty,
        LimitToProduct = false
    };




        //Step 2:  Call WebApi Controller
        var PostResult = await client.PostAsJsonAsync("api/genericdatarequest", DataRqstPmtr);
        var resultString = await PostResult.Content.ReadAsStringAsync();

        CdAssignmentType_Collection = JsonSerializer.Deserialize<IList<CdAssignmentType>>(resultString, JsonHelper.SerializationOptions);

        if (forceRefresh)
        {
            await InvokeAsync(StateHasChanged);
        }
    }


    void InsertRow()
    {
        CdAssignmentTypeGrid.InsertRow(new CdAssignmentType());
    
}

void EditRow(CdAssignmentType CdAssignmentType_Singleton)
    {
    CdAssignmentTypeGrid.EditRow(CdAssignmentType_Singleton);
}

async Task OnUpdateRow(CdAssignmentType CdAssignmentType_Singleton)
    {
    await client.PutAsJsonAsync("api/toolset", CdAssignmentType_Singleton);
    
    NotificationService.Notify(new NotificationMessage()
        {
        Severity = NotificationSeverity.Success
        ,Summary = "Successful Save"
        ,Detail = CdAssignmentType_Singleton.Name + " was saved successfully."
        ,Duration = 4000
    }
    );
    
}

async Task SaveRow(CdAssignmentType CdAssignmentType_Singleton)
    {
    
    
    await client.PutAsJsonAsync("api/CdAssignmentType", CdAssignmentType_Singleton, JsonHelper.SerializationOptions);
    
    NotificationService.Notify(new NotificationMessage()
        {
        Severity = NotificationSeverity.Success
        ,Summary = "Successful Save"
        ,Detail = CdAssignmentType_Singleton.Name + " was saved successfully."
        ,Duration = 4000
    }
    );
    
    CdAssignmentTypeGrid.CancelEditRow(CdAssignmentType_Singleton);
    
    await RequeryData(true);
}

async Task CancelEdit(CdAssignmentType CdAssignmentType_Singleton)
    {
    CdAssignmentTypeGrid.CancelEditRow(CdAssignmentType_Singleton);
    await RequeryData(true);
}

async Task DeleteRow(CdAssignmentType CdAssignmentType_Singleton)
    {
    if (CdAssignmentType_Collection.Contains(CdAssignmentType_Singleton))
        {
        
        string ConfirmHeader = "Confirm Delete";
        string ConfirmText = "Clicking 'Delete' will Remove " + CdAssignmentType_Singleton.Name;
        
        
        ConfirmOptions _ConfirmOptions = new ConfirmOptions()
            {
            OkButtonText = "Delete",
            CancelButtonText = "Cancel",
            Width = "800px"
        };
        
        var confirmResult = await DialogService.Confirm(
        ConfirmText, ConfirmHeader, _ConfirmOptions);
        
        if ((bool)confirmResult)
            {
            await client.DeleteAsync($"api/CdAssignmentType/{CdAssignmentType_Singleton.Id}");
            
            NotificationService.Notify(new NotificationMessage()
                {
                Severity = NotificationSeverity.Success
                ,Summary = "Successful Delete"
                ,Detail = CdAssignmentType_Singleton.Name + " was successfully deleted."
                ,Duration = 4000
            }
            );
            
            await RequeryData(true);
        }
    }
    
}



async Task OnCreateRow(CdAssignmentType CdAssignmentType_Singleton)
    {
    await client.PostAsJsonAsync("api/CdAssignmentType", CdAssignmentType_Singleton);
}

}

You should invoke the SaveRow method of the RadzenDataGrid. It will run validation and invoke the RowUpdate event if validation is successful. Check our online demo:

    void OnUpdateRow(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        dbContext.Update(order);

        // For demo purposes only
        order.Customer = dbContext.Customers.Find(order.CustomerID);
        order.Employee = dbContext.Employees.Find(order.EmployeeID);

        // For production
        //dbContext.SaveChanges();
    }

    async Task SaveRow(Order order)
    {
        if (order == orderToInsert)
        {
            orderToInsert = null;
        }

        await ordersGrid.UpdateRow(order);
    }

Korchev,

Thanks for your quick reply. Unless I am missing something, I do not think this is it (unless it is a problem with having the "SaveRow" method call a WebAPI.

My code contains this button in the grid (note that in trying different ideas I changed the button type from Small to Submit but it had no impact:
'''












'''

And this is the logic for SaveRow. Note that I put a breakpoing on the "PutasJsonSsync" line and can confirm that SaveRow is being called).
'''
async Task SaveRow(CdAssignmentType CdAssignmentType_Singleton)
{

await client.PutAsJsonAsync("api/CdAssignmentType", CdAssignmentType_Singleton, JsonHelper.SerializationOptions);

NotificationService.Notify(new NotificationMessage()
    {
    Severity = NotificationSeverity.Success
    ,Summary = "Successful Save"
    ,Detail = CdAssignmentType_Singleton.Name + " was saved successfully."
    ,Duration = 4000
}
);

CdAssignmentTypeGrid.CancelEditRow(CdAssignmentType_Singleton);

await RequeryData(true);

}
'''

Please let me know if I am missing someting. Thanks again.

Not sure why my button doesn't display, but trying again. It does look like it is in my original code as copied above:
'''












'''

This is exactly what it is - your SaveRow method does not call the UpdateRow method of your grid. Again - check the code which I have pasted and our online demo.

Korchev,

Thank you. This solved it.