How can I use a custom component in a Blazorise DataGrid EditTemplate

2.5k Views Asked by At

I have a Blazorise DataGrid EditTemplate such that:

            <EditTemplate>
                <Select TValue="int" SelectedValue="@((int)( context.CellValue ))" SelectedValueChanged="@(( v ) => context.CellValue = v)">
                    <SelectItem TValue="int" Value="0">All</SelectItem>
                    <SelectItem TValue="int" Value="1">Option 1</SelectItem>
                    <SelectItem TValue="int" Value="2">Option 2</SelectItem>
                </Select>
            </EditTemplate>

which works fine. I want to turn this into custom component I can reuse, so created the following:

SourcesEdit.razor:

<Select TValue="int" SelectedValue="@((int)( sourceId ))" SelectedValueChanged="@(( v ) => sourceId = v)">
    <SelectItem TValue="int" Value="0">All</SelectItem>
    <SelectItem TValue="int" Value="1">Option 1</SelectItem>
    <SelectItem TValue="int" Value="2">Option 2</SelectItem>
</Select>


@code {
    [Parameter]
    public int sourceId { get; set; }

}

Which I call with

            <EditTemplate>
                <SourcesEdit sourceId="@((int)( context.CellValue ))" />
            </EditTemplate>

The Select component is displayed and behaves correctly but the selection is not reflected in the grid after clicking save.

What am I doing wrong?

1

There are 1 best solutions below

0
enet On BEST ANSWER

Here's a code sample illustrating how to create a custom component that displays a list of values (departments) for the user to select when in edit mode. The selected option is the value displayed in display mode. If you add a new employee, the selected value is the string "Select..."

EditComponent.razor

    @typeparam TValue
    
    <Select SelectedValue="SelectedValue" SelectedValueChanged="SelectedValueChanged">
           <SelectItem TValue="string" Value="null">Select...</SelectItem>
            @foreach (var department in Departments)
             {
                 <SelectItem TValue="string" Value="@department">@department</SelectItem>
    
             }
    </Select>
    
    
    @code {
        public List<string> Departments {get;set;} = new List<string> {"Sales","IT", "Accounting"};
    
        [Parameter]
        public TValue SelectedValue { get; set; }
    
    
        [Parameter]
        public EventCallback<TValue> SelectedValueChanged { get; set; }
    }

And this is how you embed the EditComponent in the EditTemplate template in the DataGrid. Copy and test...

Usage:

@using System.ComponentModel.DataAnnotations

<DataGrid TItem="Employee"
        Data="@employees"
        TotalItems="@totalEmployees"
        Editable="true">
    <DataGridColumns>
    <DataGridCommandColumn TItem="Employee" Width="170px">
         <NewCommandTemplate>
             <Button Color="Color.Success" 
                   Clicked="@context.Clicked">New</Button>
         </NewCommandTemplate>
         <EditCommandTemplate>
             <Button Color="Color.Primary" 
                   Clicked="@context.Clicked">Edit</Button>
         </EditCommandTemplate>
         <SaveCommandTemplate>
            <Button Color="Color.Primary" 
                   Clicked="@context.Clicked">Save</Button>
          </SaveCommandTemplate>
          <DeleteCommandTemplate>
            <Button Color="Color.Danger" 
                   Clicked="@context.Clicked">Delete</Button>
          </DeleteCommandTemplate>
        <CancelCommandTemplate>
            <Button Color="Color.Secondary" 
                   Clicked="@context.Clicked">Cancel</Button>
        </CancelCommandTemplate>
                            
    </DataGridCommandColumn>                    

    <DataGridColumn TItem="Employee" Field="@nameof(Employee.ID)" Caption="#" Sortable="false" />
    <DataGridColumn TItem="Employee" Field="@nameof(Employee.FirstName)" Caption="First Name" Editable="true" />
    <DataGridColumn TItem="Employee" Field="@nameof(Employee.LastName)" Caption="Last Name" Editable="true" />
    <DataGridColumn TItem="Employee" Field="@nameof(Employee.Salary)" Caption="Salary" Editable="true">
        <DisplayTemplate>
            @($"{( context as Employee )?.Salary}")
        </DisplayTemplate>
        <EditTemplate>
            <NumericEdit TValue="decimal" Value="@((decimal)(((CellEditContext)context).CellValue))" ValueChanged="@(v=>((CellEditContext)context).CellValue=v)" />
        </EditTemplate>
    </DataGridColumn>

    <DataGridSelectColumn TItem="Employee" Field="@nameof(Employee.Department)" Caption="Department" Editable="true" >
        <DisplayTemplate>
            @($"{( context as Employee ).Department}")
        </DisplayTemplate>
        <EditTemplate>
            <EditComponent TValue="string" SelectedValue="@((string)(((CellEditContext)context)?.CellValue))" 
                                             SelectedValueChanged="@(( v ) => context.CellValue = v)"/>
        </EditTemplate>
    </DataGridSelectColumn>
</DataGridColumns>

    
</DataGrid>

@code {

   private List<Employee> employees = new List<Employee> {
         new Employee{ ID = 1, FirstName = "Nancy", LastName = "Davolio", Salary = 1000.0M, Department = "Sales" },
         new Employee{ ID = 2, FirstName = "Andrew", LastName = "Cohen", Salary = 2000.0M, Department = "IT" },
         new Employee{ ID = 3, FirstName = "David", LastName = "Copperfield", Salary = 3000.0M, Department =  "Accounting" }
     };
  private int totalEmployees = 3;
 
    public class Employee
    {
        public int ID {get;set;}
        public string FirstName {get;set;}
        public string LastName {get;set;}
        public decimal Salary {get;set;}
        
  #nullable enable  
        [Required]
        public string? Department {get;set;}
    #nullable disable   
    }
 }