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
Hi Hartmut,
Before proceeding further with your reported problem kindly share the below details to validate further at our end.
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
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
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> |
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
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.
Thank you for your cooperation, and we will do our best to resolve this issue for you as soon as possible.