Search code examples
.netblazorblazorise

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


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?


Solution

  • 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   
        }
     }