Datagrid validation

Good morning,

Using your example, I've set up a datagrid with single row editing, and I'm now trying to get some validation working.

The first thing I notice is that the validation is not triggered until I tab away from the column being validated, so if the check (save row) button is pressed before tabbing away, the validation is not being triggered?

Secondly, if I do tab away the validation is triggered and the message shows, but if I then press the check button the save is executed anyway?

I'm not using EF here, just triggering methods within the Click event of the check button.

Cheers
Reg

This is how Blazor validation works - on value change which will happen when you leave the editor.

If the property is marked with Required attribute the validation will not allow item to be saved no matter if you are using EF or not.

Hi enchev,

On answer 1, fair enough.

On answer 2, the validation is marked with the Required Attribute, but the item is being saved anyway when I click the save button.

I don't know if this affects it, but the datagrid is in a component which is linked into a Page. It's set to single edit mode.

I’m afraid that I haven’t seen such issue. Try to create minimal runnable example demonstrating the problem and I will provide details.

Ok, do you want me to upload a project showing it, or record a test and provide the source code?

You can just post a code block here similar to other posts reporting issues. A DataGrid and class definitions along with binding.

I can reproduce this by:

  1. Generating a page using the CRUD "DataGrid InLine Edit" option against the entity I'm having the problem with.

  2. Adding validations to one of the string columns - Required and Length in this case.

  3. Inserting code for the edit and save action buttons.

  4. Execute some code in the page's OnInitialisedAsync method to populate the grid from an SQL Express Database.

  5. Set up an async function linked to the save button which updates the database.

The edit button executes this code block...
await grid0.EditRow(variety);

I edit the selected row, leaving the string column with an invalid value and tab away. The validation message comes up. I then click the save button, and the async function runs and updates the database with the invalid value...

async Task SaveVariety(Variety variety)
{
try
{
DBConnection con = new DBConnection();
res = await con.ConnectToDB(true);
if(res.Status != TbiConstants.tbiresult_success)
{
TbiResultContainer.TbiResult = res;
myerrors = true;
return;
}

        if (variety.VAR_Id == 0) 
        { 
            variety.VAR_COM_Id = 1;
            res = await Varietyservice.Insert(variety);
        } 
        else 
        { 
            res = await Varietyservice.Update(variety);
        }
        switch(res.Status)
        {
        case TbiConstants.tbiresult_success :
            await con.DisconnectDB(true);
            NotificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Success, Detail = res.Message });
            await OnInitializedAsync();
            TbiGlobals.GblisDirty = false;
            deletebuttondisabled = false;
            editbuttondisabled = false;
            break;
        case TbiConstants.tbiresult_failure :
            await con.DisconnectDB(false);                
            NotificationService.Notify(new NotificationMessage { Severity = NotificationSeverity.Error, Detail = res.Message });
            break;
        default :
            await con.DisconnectDB(false);
            TbiResultContainer.TbiResult = res;
            myerrors = true;
            break;
        }
    }
    catch(Exception ex)
    {
        res.Status = TbiConstants.tbiresult_fatalerror;                                    
        res.Id = 0;
        res.Message = ex.Message;
        res.Details = ex.StackTrace;
        myerrors = true;
    }  


  }

Having done this

We will need actual runnable code to debug the problem, I am afraid that this is not complete.

Can you please remind me how to include html code in a reply? I need to use some special delimiters I think?

https://forum.radzen.com/t/faq-guidelines/5

That link gives me this..

Oops! That page doesn’t exist or is private.

@page "/varieties"

@inject IJSRuntime JSRuntime
@inject NavigationManager NavigationManager
@inject DialogService DialogService
@inject ContextMenuService ContextMenuService
@inject TooltipService TooltipService
@inject NotificationService NotificationService

@inject VarietyService Varietyservice

<PageTitle>Varieties</PageTitle>
<RadzenStack>
    <RadzenRow AlignItems="AlignItems.Center">
        <RadzenColumn Size="12" SizeMD="6">
            <RadzenText Text="Varieties" TextStyle="TextStyle.H3" TagName="TagName.H1" style="margin: 0" />
        </RadzenColumn>
        <RadzenColumn Size="12" SizeMD="6">
            <RadzenStack Orientation="Orientation.Horizontal" AlignItems="AlignItems.Center" JustifyContent="JustifyContent.End" Gap="0.5rem">
            </RadzenStack>
        </RadzenColumn>
    </RadzenRow>
    <RadzenRow>
      <RadzenColumn SizeMD=12>
        <RadzenDataGrid @ref="grid0" ColumnWidth="200px" AllowAlternatingRows="false" AllowFiltering="true" FilterMode="FilterMode.Advanced" AllowPaging="true" AllowSorting="true" ShowPagingSummary="true" 
            PageSizeOptions=@(new int[]{5, 10, 20, 30}) Data="@varieties" TItem="Variety">
            <Columns>
                    <RadzenDataGridColumn TItem="Variety" Context="varietydata" Frozen="true" Title="Actions" Sortable="false" Resizable="true" Reorderable="false" Filterable="false" Width="50px">
                        <Template Context="varietydata">
                            <RadzenButton Icon="edit" ButtonStyle="ButtonStyle.Light" Variant="Variant.Flat" Size="ButtonSize.Small" Click="@((args) => EditVariety(varietydata))" @onclick:stopPropagation="true" />
                        </Template>
                        <EditTemplate Context="varietydata">
                            <RadzenButton Icon="check" ButtonStyle="ButtonStyle.Success" Variant="Variant.Flat" Size="ButtonSize.Small" Click="@((args) => SaveVariety(varietydata))" />
                        </EditTemplate>
                    </RadzenDataGridColumn>

                <RadzenDataGridColumn TItem="Variety" Property="VAR_Id" Title="V A R Id">
                  <EditTemplate Context="variety">
                      <RadzenNumeric style="display: block; width: 100%" @bind-Value="@variety.VAR_Id" Name="VAR_Id" />
                  </EditTemplate>
                </RadzenDataGridColumn>
                <RadzenDataGridColumn TItem="Variety" Property="VAR_Name" Title="V A R Name">
                  <EditTemplate Context="varietydata">
                      <RadzenTextBox style="display: block; width: 100%" @bind-Value="@varietydata.VAR_Name" Name="VAR_Name" />
                      <RadzenRequiredValidator Text="Name is Required" Component="VAR_Name"/>
                      <RadzenLengthValidator Text="Name length must be between 5 and 50" Style="display:block; position:relative; z-index: 1"  Component="VAR_Name" Min="5" Max="50" />                      
                  </EditTemplate>
                </RadzenDataGridColumn>
                <RadzenDataGridColumn TItem="Variety" Property="VAR_COM_Id" Title="V A R C O M Id">
                  <EditTemplate Context="variety">
                      <RadzenNumeric style="display: block; width: 100%" @bind-Value="@variety.VAR_COM_Id" Name="VAR_COM_Id" />
                  </EditTemplate>
                </RadzenDataGridColumn>
                <RadzenDataGridColumn TItem="Variety" Property="VAR_Status" Title="V A R Status">
                  <EditTemplate Context="variety">
                      <RadzenTextBox style="display: block; width: 100%" @bind-Value="@variety.VAR_Status" Name="VAR_Status" />
                  </EditTemplate>
                </RadzenDataGridColumn>
            </Columns>

        </RadzenDataGrid>

    </RadzenColumn>
  </RadzenRow>
</RadzenStack>

@code {
    protected IEnumerable<Tbi.Data.Models.Variety> varieties;

    protected RadzenDataGrid<Tbi.Data.Models.Variety> grid0;

    protected override async Task OnInitializedAsync() 
    {
            DBConnection con = new DBConnection();
            var res = await con.ConnectToDB(false); //opens connections to ms sql express database
            var results = await(Varietyservice.GetAll(1,true,false)); //Select * from Variety
            varieties = results.Item2;
            await con.DisconnectDB(); //disconnects from database
    }

    //=================================================================================================================================================================================
    async Task EditVariety(Variety variety)
    {
    await grid0.EditRow(variety);
    }

    async Task SaveVariety(Variety variety)
    {   
        try
        {
            DBConnection con = new DBConnection();
            var res = await con.ConnectToDB(true);           
            res = await Varietyservice.Update(variety); //UPDATE Variety ....
            await con.DisconnectDB(true);
        }
        catch(Exception ex)
        {

        }  
      }
}

and the model used is

using Microsoft.EntityFrameworkCore;

namespace Tbi.Data.Models
{
    [Index(nameof(VAR_Name), IsUnique = true)]
    public class Variety
    {
        public int VAR_Id { get; set; }

        public string VAR_Name { get; set; }

        public int VAR_COM_Id { get; set; }

        public string VAR_Status { get; set; }

        public Byte[] VAR_Timestamp { get; set; }
    }
}

I don’t see any Required attributes on your properties.

This is what you wrote previously.

In the html, on the Name column. Or are you referring to the model?

Ah. So I need to annotate the model as well as include the validation tags!

Thanks enchev...

CRUD pages will read your model to create pages . Yes, I am referring the model.

Hi again,

But what if I'm not using CRUD? What if I just have a normal Page I've coded myself? Will the model still be referred to?

Is there an example anywhere showing how to use inline editing on a datagrid that's not related to CRUD?

Cheers
Reg

CRUD pages wizard will read your model to create the pages like if you do it manually.