selected row background color in master details grid

I have a SF master details grid which works fine. In one of your online-samples the selected row in the master grid has a background color when the details open. This does not happen with my master grid, only in the details grid a selected row is highlighted.

How can I set the background color of the selected row in the master grid, before the details table opens?


Thanx, Hartmut


5 Replies

PS Prathap Senthil Syncfusion Team November 29, 2023 12:50 PM UTC

Hi Hartmut,

Before proceeding further with your reported problem kindly share the below details to validate further at our end.


  1. Share with us the entire grid code snippet along with the model class.
  2. Please share with us a simple issue reproducible sample.
  3. Are you facing an issue where selecting the row does not apply the row background color?
  4. Share the screenshot or video demonstration of the issue, it will be more useful to us.
  5. Share with us the NuGet version you have used.

The above-requested details will be very helpful for us to validate the reported query at our end and provide the solution as early as possible.


Regards,
Prathap S



HA Hartmut replied to Prathap Senthil November 29, 2023 04:32 PM UTC

Dear Prothap,

the code of the datagrid is shown below, I hope it is sufficient to answer my question.

The question is:

when i click on one row of the master grid so that the details grid expands, how can I set or modify the color of the selected row in the master grid?

And how can I restor the background when the details grid collapses?


@page "/Solution"

@page "/Solution/{StudyOrProjectId:long}/{Property}/{StudyOrProjectName}"

@using System.Text

@using Syncfusion.Blazor.Popups

@using myBlazorLab_g.Helpers

@using Microsoft.AspNetCore.Components

@using Syncfusion.Blazor.Inputs


@inject ISolutionService SolutionService

@inject IIngredientService IngredientService

@inject IJSRuntime Runtime

@inject IBuildWhereExpression BuildWhereExpression



<div style="margin-right:50px">


    <!--Parent configuration-->

    <SfGrid ID="parentGridID" @ref="_parentGrid" DataSource="@_solutionModelList" AllowSorting="true" EnableHover="false" AllowSelection="false"

            AllowPaging="true" AllowTextWrap="true" Toolbar="@(new string[] {"Add", "Edit" ,"Delete","UpdateXXX","Cancel" })">

        <GridPageSettings PageSizes="true"></GridPageSettings>


        <!-- create the events we need to capture-->

        <GridEvents OnActionBegin="OnActionBegin" OnActionComplete="OnActionComplete" TValue="SolutionModel" />


        <GridEditSettings AllowEditing="true" Mode="@EditMode.Dialog">

            <Template>

                @{

                    var selectedSolution = (context as SolutionModel);

                    <div>

                        <div class="form-row">

                            <div class="form-group col-md-12">

                                <label class="e-float-text e-label-top">Playlist Name</label>

                                <SfTextBox ID="Parent" bind-Value="@(selectedSolution.SolName)" Multiline="true"></SfTextBox>

                            </div>

                        </div>

                        <div class="form-row">

                            <div class="form-group col-md-12">

                                <label class="e-float-text e-label-top">Comments</label>

                                <SfTextBox ID="ParentOwnerComments" bind-Value="@(selectedSolution.PreparePerson)" Multiline="true"></SfTextBox>

                            </div>

                        </div>


                    </div>

                }

            </Template>

        </GridEditSettings>


        <!--collaps all DetailTemplates but one-->

        <GridEvents DetailDataBound="DetailDataBound" DataBound="DataBound" TValue="SolutionModel"></GridEvents>


        <!--Child Grid configuration-->

        <GridTemplates>


            <DetailTemplate>

                @{

                    // this creates an object based on the data Model and values held in the selected data row

                    var parentSolution = (context as SolutionModel);


                    // use the parent row as a key to query the child data in the database.

                    // The database call is asyn, so we have to wait for it to complete otherwise the datasource won't have updated before the grid is re-drawn

                    GetDetails(parentSolution);


                    <SfTab Height="auto" HeaderPlacement="HeaderPosition.Top">


                        <TabItems>


                            <TabItem>

                                <ChildContent>

                                    <TabHeader Text="@("Usage Details of " + _ingredientList.FirstOrDefault()?.SolName)"></TabHeader>

                                </ChildContent>


                                <ContentTemplate>

                                    <SfGrid ID="SolutionUsageListID" @ref="_childGrid" TValue="SolutionUsageModel" DataSource="_solutionUsageList" AllowSorting="true" EnableHover="false" AllowSelection="true"

                                            AllowPaging="true" AllowTextWrap="true">


                                        <GridPageSettings PageCount="5" PageSizes="true" PageSize="10"></GridPageSettings>


                                        <GridEvents TValue="SolutionUsageModel"/>


                                        <GridEditSettings AllowEditing="true" Mode="@EditMode.Dialog">


                                            <Template Context="childDialog">

                                                @{

                                                    var selectedSolUsage = (context as SolutionUsageModel);

                                                }

                                            </Template>


                                        </GridEditSettings>


                                        <GridColumns>


                                            <GridColumn HeaderText="Solution Id" Field="@nameof(SolutionUsageModel.SolutionId)"></GridColumn>

                                            <GridColumn HeaderText="Usage Id" Field="@nameof(SolutionUsageModel.UsageId)"></GridColumn>

                                            <GridColumn HeaderText="Created on" Field="@nameof(SolutionUsageModel.CreatedDate)" Format="yyyy-MM-dd"></GridColumn>

                                            <GridColumn HeaderText="Project" Field="@nameof(SolutionUsageModel.ProjectName)"></GridColumn>

                                            <GridColumn HeaderText="Study Id" Field="@nameof(SolutionUsageModel.StudyId)"></GridColumn>

                                            <GridColumn HeaderText="Study" Field="@nameof(SolutionUsageModel.StudyName)"></GridColumn>

                                            <GridColumn HeaderText="Used on" Field="@nameof(SolutionUsageModel.UseDate)" Format="yyyy-MM-dd"></GridColumn>

                                            <GridColumn HeaderText="Used by" Field="@nameof(SolutionUsageModel.UsedBy)"></GridColumn>

                                        </GridColumns>


                                    </SfGrid>

                                </ContentTemplate>

                            </TabItem>


                            <TabItem>

                                <ChildContent>

                                    <TabHeader Text="@("Composition of " + _ingredientList.FirstOrDefault()?.SolName)"></TabHeader>

                                </ChildContent>


                                <ContentTemplate>


                                    <SfGrid ID="IngredientListID" @ref="_ingredGrid" TValue="IngredientModel" DataSource="_ingredientList" AllowSorting="true" EnableHover="false" AllowSelection="true"

                                            AllowPaging="true" AllowTextWrap="true">


                                        <GridEvents TValue="IngredientModel"/>


                                        <GridPageSettings PageCount="5" PageSizes="true"></GridPageSettings>


                                        <GridEditSettings AllowEditing="true" Mode="@EditMode.Dialog">


                                            <Template Context="ingredDialog">

                                                @{

                                                    var selectedIngred = (context as IngredientModel);

                                                }

                                            </Template>


                                        </GridEditSettings>


                                        <GridColumns>

                                            <GridColumn HeaderText="Solution Id" Field="@nameof(IngredientModel.SolutionId)"></GridColumn>

                                            <GridColumn HeaderText="Ingredient Id" Field="@nameof(IngredientModel.IngredientId)"></GridColumn>


                                            <GridColumn HeaderText="Chemical Id" Field="@nameof(IngredientModel.ChemicalId)"></GridColumn>

                                            <GridColumn HeaderText="ContainsSolId" Field="@nameof(IngredientModel.ContainsSolId)"></GridColumn>

                                            <GridColumn HeaderText="Chemical" Field="@nameof(IngredientModel.Ingredient)"></GridColumn>

                                            <GridColumn HeaderText="Amount" Field="@nameof(IngredientModel.Amount)"></GridColumn>

                                            <GridColumn HeaderText="Dimension" Field="@nameof(IngredientModel.Dimension)"></GridColumn>

                                        </GridColumns>


                                    </SfGrid>

                                </ContentTemplate>


                            </TabItem>


                        </TabItems>

                    </SfTab>

                }

            </DetailTemplate>

        </GridTemplates>



        <!-- more parent data grid -->

        <GridColumns>


            <GridColumn HeaderText="@GridHeaderText" TextAlign="TextAlign.Center" CustomAttributes="@(new Dictionary<string,object>() {{"class","e-attr"}})">


                <GridColumns>

                    <GridColumn HeaderText="Solution Id" Field="@nameof(SolutionModel.SolutionId)" TextAlign="TextAlign.Center"></GridColumn>

                    <GridColumn HeaderText="Solution Name" Field="@nameof(SolutionModel.SolName)" TextAlign="TextAlign.Center"></GridColumn>

                    <GridColumn HeaderText="Preparation Date" Field="@nameof(SolutionModel.PrepareDate)" Format="yyyy-MM-dd" TextAlign="TextAlign.Center"></GridColumn>

                    <GridColumn HeaderText="Expiry Date" Field="@nameof(SolutionModel.ExpiryDate)" Format="yyyy-MM-dd" TextAlign="TextAlign.Center"></GridColumn>

                    <GridColumn HeaderText="Prepared By" Field="@nameof(SolutionModel.PreparedBy_Name)" TextAlign="TextAlign.Center"></GridColumn>

                    <GridColumn HeaderText="Creation Date" Field="@nameof(SolutionModel.CreatedDate)" Format="yyyy-MM-dd" TextAlign="TextAlign.Center"></GridColumn>

                    <GridColumn HeaderText="Update Date" Field="@nameof(SolutionModel.UpdatedDate)" Format="yyyy-MM-dd" TextAlign="TextAlign.Center"></GridColumn>

                </GridColumns>


            </GridColumn>


        </GridColumns>


    </SfGrid>


</div>




@code {


    [Parameter]

    public long StudyOrProjectId { get; set; }

    [Parameter]

    public string StudyOrProjectName { get; set; } = String.Empty;

    [Parameter]

    public string Property { get; set; } = String.Empty;


    private string GridHeaderText { get; set; } = "";


    List<SolutionModel> _solutionModelList = new();

    List<SolutionUsageModel> _solutionUsageList = new();

    List<IngredientModel> _ingredientList = new();


    // settings for the grids

    SfGrid<SolutionModel>? _parentGrid;

    SfGrid<SolutionUsageModel>? _childGrid;

    SfGrid<IngredientModel>? _ingredGrid;


    // settings for the confirm dialog ??

    public bool ShowButtons { get; set; } = true;

    public bool AlertVisibility { get; set; } = false;

    public bool ConfirmDlgVisible { get; set; } = false;

    public bool PromptDlgVisible { get; set; } = false;

    private bool SaveConfirmedFlag { get; set; } = false;


    // for collapsing all Detail Templates but one

     SolutionModel? target = new();


    protected override async Task OnParametersSetAsync()

    {

        _solutionModelList = await SolutionService.GetSolutions(Property, StudyOrProjectId);

        RefreshList();

    }


    private void RefreshList()

    {

        var text = Property.Substring(0, Property.Length - 2);

        var text2 = text == "Study" ? " A&M " : " ";

        StringBuilder gridHeaderText = new StringBuilder();


        if (StudyOrProjectId == 0)

        {

            gridHeaderText.Append("List of solutions used in all ");

            var text3 = text == "Study" ? "Studies" : "Projects";

            gridHeaderText.Append(text3);

        }

        else

        {

            gridHeaderText.Append("List of solutions used in ");

            gridHeaderText.Append(text);

            gridHeaderText.Append(text2);

            gridHeaderText.Append(StudyOrProjectName);

        }


        GridHeaderText = gridHeaderText.ToString();

        StateHasChanged();

    }


    // accepts an object of selected row of parent data from the grid and calls the async database.

    public async void GetDetails(SolutionModel value)

    {

        _solutionUsageList = value.SolUsagesModel.ToList();

        //var id = _solutionUsageList.First().SolutionId;


        var id = value.SolutionId;


        _ingredientList = await IngredientService.GetIngredients(id);

    }



    public void SaveDialogOpenedEvent(Syncfusion.Blazor.Popups.BeforeOpenEventArgs args)

    {

        // hide the buttons on the main data editing dialog

        this.ShowButtons = false;

    }

    public void SaveDialogClosedEvent(CloseEventArgs args)

    {

        // show the buttons on the main ata editing dialog

        this.ShowButtons = true;

    }


    // the user pressed NO on the save Dialog

    public void SaveDialogNotConfirmed(Object e)

    {

        this.AlertVisibility = false;

        this.ConfirmDlgVisible = false;

        this.PromptDlgVisible = false;

    }


    // the user pressed YES on the save Dialog

    public void SaveDialogSaveConfirmed(Object e)

    {

        this.ConfirmDlgVisible = false;

        this.SaveConfirmedFlag = true;

        _parentGrid.EndEditAsync(); //Save the changes to Grid programatically.

    }



    public void OnActionBegin(ActionEventArgs<SolutionModel> Args)

    {

        if (Args.RequestType == Syncfusion.Blazor.Grids.Action.Add)

        {


        }


        if (Args.RequestType == Syncfusion.Blazor.Grids.Action.Save)

        {

            if (Args.Action == "Add")

            {

                //some code....

            }

            else if (!SaveConfirmedFlag)

            {

                this.ConfirmDlgVisible = true;

                Args.Cancel = true; //cancel the save action


            }

        }

        if (Args.RequestType == Syncfusion.Blazor.Grids.Action.Delete)

        {

            //some code....

        }

        if (Args.RequestType == Syncfusion.Blazor.Grids.Action.BeginEdit && SaveConfirmedFlag)

        {


            SaveConfirmedFlag = false;

        }


    }

    public void OnActionComplete(ActionEventArgs<SolutionModel> Args)

    {

        if (Args.RequestType == Syncfusion.Blazor.Grids.Action.Save)

        {

            var changedData = Args.Data;

        }

    }



    // collaps all Details but one


    public bool firstrender { get; set; } = true;


    public async Task DataBound()

    {

        if (firstrender)

        {

            var dotNetReference = DotNetObjectReference.Create(this);

            await Runtime.InvokeAsync<string>("detail", dotNetReference);

            firstrender = false;

        }

    }

    public async Task DetailDataBound(DetailDataBoundEventArgs<SolutionModel> args)

    {

        if (target != null)

        {

            if (target == args.Data)

            {

                return;

            }

            await _parentGrid.ExpandCollapseDetailRowAsync(target);

        }

        target = args.Data;

    }


    [JSInvokable("DetailCollapse")]

    public void DetailRowCollapse()

    {

        target = null;

    }


}




<style>



    /* header cells from master grid, col headings both master and details grid */

    .e-grid .e-headercell, .e-grid .e-detailheadercell {

        background: lightgray;

    }


    /* header above main grid */

    .e-grid .e-stackedheadercelldiv {

        font-size:24px;

    }


    /* col headings both master and details grid*/

    .e-grid .e-headercelldiv {

        font-size: 18px;

    }


    /* details col headings only, overriden from above (?) */

    .e-detailcell .e-grid .e-headercell {

        background-color: #f2f2f2;

    }


    /* all grid cells, master and details*/

    .e-grid .e-rowcell {

        font-size: 18px;

    }




    /*-----------------------------------------------------------------------------------*/


    .e-tab .e-tab-header .e-toolbar-item .e-tab-text {

        font-size: 18px;

    }


    .e-tab {

        border: 5px solid lightgrey;

        border-radius: 8px;

        margin: 5px;

    }


    /* selected tab header text*/

    /* .e-tab .e-tab-header .e-toolbar-item.e-active.e-ileft .e-tab-text {

            color: black !important;

            font-weight: bold;

        }

    */


    /*-----------------------------------------------------------------------------------*/


    /* selected tab header text*/

    .e-tab .e-tab-header .e-toolbar-items .e-active.e-ileft .e-tab-text {

        color: black !important;

        font-weight: bold;

    }



    .e-tab .e-tab-header .e-toolbar-item:not(.e-active.e-ileft) .e-tab-text {

        color: black !important;


    }


    /*-----------------------------------------------------------------------------------*/


    /* selected tab header background color*/

    .e-tab .e-tab-header .e-toolbar-items .e-active .e-tab-wrap {

        background-color: #dcdcdc;

    }



    .e-tab .e-tab-header .e-toolbar-item:not(.e-active) .e-tab-wrap:hover {

        background-color: #f2f2f2;

        color:#000;

    }


    /*-----------------------------------------------------------------------------------*/


    /* selected tab headerbackground*/

    .e-tab .e-tab-header .e-toolbar-item.e-active {

        background: lightblue;

    }


</style>


Regards

Hartmut




PS Prathap Senthil Syncfusion Team December 1, 2023 03:06 AM UTC

Based on your requirement, we suggest you use the below CSS customization to achieve your requirements . Kindly refer to the below code snippet and sample for your reference.

<style>

    .e-grid .e-gridcontent .e-row .e-detailrowexpand, .e-grid .e-gridcontent .e-row .e-detailrowexpand ~ .e-rowcell {

        background-color: aquamarine;

    }

 

 

</style>

A screenshot of a computer

Description automatically generated



Sample Link: https://blazorplayground.syncfusion.com/embed/hDVgWWKjfJWVBdit?appbar=true&editor=true&result=true&errorlist=true&theme=bootstrap5



HA Hartmut replied to Prathap Senthil December 2, 2023 10:51 AM UTC

Dear Prathap,

thank you for your answere. I copied your solution above into my application, but it does not work. I removed all <styles> from my application, but it still did not work. Than I copied the complete razor-page from your solution into my application, and that worked. So I guess something is wrong with my code. I will try to change your code step by step until it has the full functionality of my code, and I will look when the highlighting is lost,


Hartmut



PS Prathap Senthil Syncfusion Team December 4, 2023 12:51 PM UTC

Thanks for the Update,

We were unable to reproduce the reported issue.If the issue persists, to assist you further, we request that you provide us with additional details.

  • Could you please share an issue-reproducible sample with duplicate data?
  • If possible, kindly share with us your attempts to reproduce the reported issue on the below-mentioned sample.

Thank you for your cooperation, and we will do our best to resolve this issue for you as soon as possible.


Loader.
Up arrow icon