HI Syncfusion Team,
I've first searched the Blazor forum for answers before making a new thread. I can't find a solution within the Blazor forum.
BTW: I'm using Blazor Server and Syncfusion 20.3.0.56 (downloaded all the components individually).
My question: Is it possible to change the font color of a cell in SfGrid? Example. I have a STATUS column (string). It's either "Active" or "Inactive". I want the font color of the cell that is "Active" to be green and the "Inactive" to be red. Cell font color only. (not row color.) I tried the QueryCellInfo but It does not seem to work. Are there any breaking changes for the 20.3.0.56?
My code below:
<SfGrid DataSource="@users"
Toolbar="@Toolbaritems"
AllowSorting="true"
AllowFiltering="false"
AllowPaging="false"
AllowResizing="true"
AllowGrouping="false"
Width="1050">
<GridEvents QueryCellInfo="QueryCellInfoHandler" TValue="UserModel"></GridEvents>
<GridFilterSettings Type="Syncfusion.Blazor.Grids.FilterType.Menu"></GridFilterSettings>
<GridPageSettings PageSize="7"></GridPageSettings>
<GridColumns>
<GridColumn Field="@nameof(UserModel.FullName)"
HeaderText="Full Name"
TextAlign="TextAlign.Left"
Width="20">
</GridColumn>
<GridColumn Field="@nameof(UserModel.Email)"
HeaderText="Email Address"
TextAlign="TextAlign.Left"
Width="15">
</GridColumn>
<GridColumn Field="@nameof(UserModel.Username)"
HeaderText="User Name"
TextAlign="TextAlign.Left"
Width="12">
</GridColumn>
<GridColumn Field="@nameof(UserModel.Role)"
HeaderText="Role"
TextAlign="TextAlign.Left"
Width="12">
</GridColumn>
<GridColumn Field="@nameof(UserModel.Staffing)"
HeaderText="Staffing"
TextAlign="TextAlign.Left"
Width="12">
</GridColumn>
<GridColumn Field="@nameof(UserModel.Status)"
HeaderText="Status"
TextAlign="TextAlign.Left"
Width="12">
</GridColumn>
<GridColumn Field="@nameof(UserModel.AccountStatus)"
HeaderText="Active/Disabled"
TextAlign="TextAlign.Left"
Width="15">
</GridColumn>
</GridColumns>
<GridEvents OnToolbarClick="ToolbarClickHandler" TValue="UserModel"></GridEvents>
<GridEvents RowSelected="RowSelectHandler" OnToolbarClick="ToolbarClickHandler" TValue="UserModel"></GridEvents>
</SfGrid>
public void QueryCellInfoHandler(QueryCellInfoEventArgs<UserModel> args)
{
if (args.Data.AccountStatus == "Active")
{
args.Cell.AddClass(new string[] { "active" });
}
else
{
args.Cell.AddClass(new string[] { "disabled" });
}
}
<style>
.e-grid .e-gridcontent .e-rowcell.active {
color: green;
}
.e-grid .e-gridcontent .e-rowcell.disabled {
color: red !important;
}
</style>
Any help will be very appreciated.
Oliver
Hi Oliver,
Greetings from Syncfusion support,
We created an example sample based on your requirements. Kindly refer to the below code snippet and the sample solution for your reference.
public void CustomizeCell(QueryCellInfoEventArgs<Order> args) { if (args.Column.Field == "ShipCity") { if (args.Data.ShipCity == "London") { args.Cell.AddClass(new string[] { "london" }); } else { args.Cell.AddClass(new string[] { "redmond" }); } } }
<style> .london { color:greenyellow !important; }
.redmond{ color:red !important; } |
Regards,
Prathap S
Thanks for the reply. The attached solution works perfectly. This is what I wanted. But for some reason the code does not work and I can't make heads or tails about it. I don't have any special css files whatsoever. The weird effect is the css is applied on my navbar sidebar. I dont have any special css on my sidebar css isolation.
Attaching my full code:
@page "/userpage"
@implements IDisposable
@attribute [Authorize(Roles = "Administrator")]
@using Syncfusion.Blazor
@using Syncfusion.Blazor.Spinner
@inject IUserService UserService
@inject IUserTypeService UserTypeService
@inject NavigationManager NavigationManager
@inject Blazored.SessionStorage.ISessionStorageService session
@inject Microsoft.Extensions.Configuration.IConfiguration config
@inject AuthenticationStateProvider authStateProvider
@using System.Timers
<div id="container" style="background-color:azure;">
<h3 style="padding:10px;">User Page</h3>
<div id="grid">
<SfGrid DataSource="@users"
Toolbar="@Toolbaritems"
AllowSorting="true"
AllowFiltering="true"
AllowPaging="true"
AllowResizing="true"
AllowGrouping="false">
<GridFilterSettings Type="Syncfusion.Blazor.Grids.FilterType.Menu"></GridFilterSettings>
<GridPageSettings PageSize="7"></GridPageSettings>
<GridEvents QueryCellInfo="CustomizeCell" TValue="Users"></GridEvents>
<GridColumns>
<GridColumn Field="@nameof(Users.FullName)"
HeaderText="Full Name"
TextAlign="TextAlign.Left"
Width="20">
</GridColumn>
<GridColumn Field="@nameof(Users.Email)"
HeaderText="Email Address"
TextAlign="TextAlign.Left"
Width="15">
</GridColumn>
<GridColumn Field="@nameof(Users.UserName)"
HeaderText="User Name"
TextAlign="TextAlign.Left"
Width="15">
</GridColumn>
<GridColumn Field="@nameof(Users.UserType)"
HeaderText="User Type"
TextAlign="TextAlign.Left"
Width="15">
</GridColumn>
<GridColumn Field="@nameof(Users.Status)"
HeaderText="Status"
TextAlign="TextAlign.Left"
Width="15">
</GridColumn>
</GridColumns>
<GridEvents OnToolbarClick="ToolbarClickHandler" TValue="Users"></GridEvents>
<GridEvents RowSelected="RowSelectHandler" OnToolbarClick="ToolbarClickHandler" TValue="Users"></GridEvents>
</SfGrid>
<br />
<br />
<span style="color:green; font-weight:700;">@dateTimeValue</span>
<SiteFooter></SiteFooter>
</div>
</div>
@*================GENERIC DIALOG =================*@
<div>
<SfDialog @ref=GenericDialog IsModal="true" Width="400px" ShowCloseIcon="true" Visible="false">
<DialogTemplates>
<Header> Attention! </Header>
<Content>
<div class='error-detail col-lg-12'>
<span> @GenericMessage </span>
</div>
</Content>
</DialogTemplates>
<DialogButtons>
<DialogButton Content="OK" IsPrimary="true" OnClick="@CloseGenericDialog" CssClass="dialog-width" />
</DialogButtons>
<DialogAnimationSettings Effect="@AnimationEffect" Duration=400 />
</SfDialog>
</div>
@*================ WARNING DELETE =================*@
<div>
<SfDialog @ref="DialogDelete" IsModal="true" Width="400px" ShowCloseIcon="true" Visible="false">
<DialogTemplates>
<Header> Confirm @DisableText User </Header>
<Content>
<div class='error-detail col-lg-12'>
<span> Please confirm that you want to @DisableText this record. </span>
<br> (@DeleteItem)
</div>
</Content>
</DialogTemplates>
<DialogAnimationSettings Effect="@AnimationEffect" Duration=400 />
<DialogButtons>
<DialogButton Content="@DisableText" IsPrimary="true" OnClick="@ConfirmDeleteYes" CssClass="dialog-width" />
<DialogButton Content="Cancel" IsPrimary="false" OnClick="@ConfirmDeleteNo" CssClass="dialog-width" />
</DialogButtons>
</SfDialog>
</div>
@*=====================Add Edit GL Dialog =========================*@
<div class="container">
<SfDialog @ref="DialogAddEditUser" IsModal="true" Width="500px" ShowCloseIcon="true" Visible="false">
<DialogTemplates>
<Header>@HeaderText</Header>
</DialogTemplates>
<DialogAnimationSettings Effect="@AnimationEffect" Duration=400 />
<EditForm Model="@AddEditUser" OnValidSubmit="@UserAddEditSave">
<DataAnnotationsValidator />
<div style="padding:10px">
<SfTextBox Enabled="true" Placeholder="Full Name"
FloatLabelType="@FloatLabelType.Always"
@bind-Value="AddEditUser.FullName"></SfTextBox>
<ValidationMessage style="font-size:0.7rem;" For="@(() => AddEditUser.FullName)" />
<SfTextBox Enabled="true" Placeholder="Email Address"
FloatLabelType="@FloatLabelType.Always"
@bind-Value="AddEditUser.Email"></SfTextBox>
<ValidationMessage style="font-size:0.7rem;" For="@(() => AddEditUser.Email)" />
<SfTextBox Enabled="true" Placeholder="Username"
FloatLabelType="@FloatLabelType.Always"
@bind-Value="AddEditUser.UserName"></SfTextBox>
<ValidationMessage style="font-size:0.7rem;" For="@(() => AddEditUser.UserName)" />
<SfTextBox Enabled="true" Placeholder="Password"
FloatLabelType="@FloatLabelType.Always"
@bind-Value="AddEditUser.UserPassword"
Type="InputType.Password"></SfTextBox>
<ValidationMessage style="font-size:0.7rem;" For="@(() => AddEditUser.UserPassword)" />
<SfTextBox Enabled="true" Placeholder="Confirm Password"
FloatLabelType="@FloatLabelType.Always"
@bind-Value="AddEditUser.ConfirmPassword"
Type="InputType.Password"></SfTextBox>
<ValidationMessage style="font-size:0.7rem;" For="@(() => AddEditUser.ConfirmPassword)" />
<SfDropDownList DataSource="@userType"
TItem="UserType"
TValue="int"
Text="UserTypeID"
@bind-Value="AddEditUser.UserTypeID"
FloatLabelType="@FloatLabelType.Always"
Placeholder="Select a User Type"
Width="200px">
<ValidationMessage style="font-size:0.7rem;" For="@(() => AddEditUser.UserTypeID)" />
<DropDownListFieldSettings Text="UserTypeName" Value="UserTypeID"></DropDownListFieldSettings>
<DropDownListEvents TItem="UserType" TValue="int" ValueChange="OnChangeUserType"></DropDownListEvents>
</SfDropDownList>
</div>
<br />
<div class="e-footer-content">
<div class="button-container">
<button type="submit" class="e-btn e-normal e-primary" style="width:100px" disabled=@isSubmitting>Save</button>
<button type="button" class="e-btn e-normal" @onclick="@CloseDialogAddEdit" style="width:100px">Cancel</button>
</div>
</div>
</EditForm>
</SfDialog>
</div>
@code {
//Get SessionUser
public UserInfo sessionuser;
//=== para ni ma trap ang overzealous na dialog ===========
bool isSubmitting;
//SF Dialog Declations
SfDialog GenericDialog;
SfDialog DialogDelete;
SfDialog DialogAddEditUser;
private string GenericMessage = "";
//Supplier Variable declarations
IEnumerable<Users> users;
private int SelectedUserID;
Users AddEditUser = new Users();
string HeaderText = "";
string DeleteItem = "";
string DisableText = "";
//====== synfuxsion palabok ====================
private DialogEffect AnimationEffect = DialogEffect.Zoom;
//sfgrid variable declarations
private List<ItemModel> Toolbaritems = new List<ItemModel>();
//UsertTypes Variable Declarations
IEnumerable<UserType> userType;
private int SelectedUserTypeID;
private Timer timer;
private string dateTimeValue;
protected override async Task OnInitializedAsync()
{
//Populate the list of Companies for the Companies combobox
users = await UserService.UsersList();
//Populate the User Type list for combobox
userType = await UserTypeService.UserTypeList();
//Populate toolbaritems for SFGrid
Toolbaritems.Add(new ItemModel() { Text = "Add", TooltipText = "Add a new User", PrefixIcon = "e-add" });
Toolbaritems.Add(new ItemModel() { Text = "Edit", TooltipText = "Edit selected User", PrefixIcon = "e-edit" });
Toolbaritems.Add(new ItemModel() { Text = "Enable/Disable", TooltipText = "Delete selected User", PrefixIcon = "e-delete" });
//Get session user
sessionuser = await session.GetItemAsync<UserInfo>("BlazoredSessionUser");
StartTimer();
}
public void Dispose()
{
timer.Dispose();
}
private void StartTimer()
{
timer = new Timer();
timer.Interval = 5000;
timer.Elapsed += OnTimerElapsed;
timer.Enabled = true;
}
private async void OnTimerElapsed(object? sender, ElapsedEventArgs e)
{
users = await UserService.UsersList();
dateTimeValue = DateTime.Now.ToString("MM-dd-yyyy hh:mm:ss tt");
await InvokeAsync(() =>
{
StateHasChanged();
});
}
//============= Close Generic Dialog ================
private async Task CloseGenericDialog()
{
await this.GenericDialog.HideAsync();
}
//===== code for deleting GL record =============
public async Task ConfirmDeleteYes()
{
int Success = await UserService.UsersDelete(SelectedUserID);
if (Success != 0)
{
GenericMessage = "User can't be deleted";
await this.GenericDialog.ShowAsync();
}
else
{
await this.DialogDelete.HideAsync();
users = await UserService.UsersList();
StateHasChanged();
}
}
//==== cancel delete GL Record ============
public async void ConfirmDeleteNo()
{
await this.DialogDelete.HideAsync();
}
//====== code to get UserID from the Grid ===================
public void RowSelectHandler(RowSelectEventArgs<Users> args)
{
//{args.Data} returns the current selected records.
SelectedUserID = args.Data.UserID;
DeleteItem = args.Data.FullName;
if (args.Data.Status == "Disabled")
{
DisableText = "Enable";
}
else
{
DisableText = "Disable";
}
}
//============ Grid Toolbaritems Add Edit Delete Code SHOW ONLY ============================
public async Task ToolbarClickHandler(Syncfusion.Blazor.Navigations.ClickEventArgs args)
{
if (args.Item.Text == "Add")
{
SelectedUserID = 0;
AddEditUser = new Users();
HeaderText = "Add User";
await this.DialogAddEditUser.ShowAsync();
}
if (args.Item.Text == "Edit")
{
if (SelectedUserID == 0)
{
GenericMessage = "Please select a User to Edit.";
await this.GenericDialog.ShowAsync();
}
else
{
//populate addedituser object for data editing
HeaderText = "Edit User";
AddEditUser = await UserService.Users_GetOne(SelectedUserID);
await this.DialogAddEditUser.ShowAsync();
}
}
if (args.Item.Text == "Enable/Disable")
{
//code for deleting
if (SelectedUserID > 0)
{
await this.DialogDelete.ShowAsync();
}
else
{
//no record selected
GenericMessage = "Please select a User to Disable/Enable.";
await this.GenericDialog.ShowAsync();
}
}
}
//====== code add/edit GL Record SAVING DATA =====================
protected async Task UserAddEditSave()
{
if (isSubmitting)
return;
isSubmitting = true;
try
{
var customAuthStateProvider = (CustomAuthenticationStateProvider)authStateProvider;
string appkey = config["SyncfusionLicenceKey"];
//===== code adding user record if selected userid is 0
if (SelectedUserID == 0)
{
int Success = await UserService.UsersInsert(AddEditUser.FullName,
AddEditUser.Email,
AddEditUser.UserName,
Encrypt.ToSHA256(AddEditUser.UserPassword + appkey),
Encrypt.ToSHA256(AddEditUser.ConfirmPassword + appkey),
AddEditUser.UserTypeID,
sessionuser.UserID);
if (Success == 0)
{
await this.DialogAddEditUser.HideAsync();
users = await UserService.UsersList();
this.StateHasChanged();
}
else
{
//Error
GenericMessage = "Something went wrong. Invalid Password";
await this.GenericDialog.ShowAsync();
}
}
else
{
int Success = await UserService.UsersUpdate(AddEditUser.UserID,
AddEditUser.FullName,
AddEditUser.Email,
AddEditUser.UserName,
Encrypt.ToSHA256(AddEditUser.UserPassword + appkey),
Encrypt.ToSHA256(AddEditUser.ConfirmPassword + appkey),
AddEditUser.UserTypeID,
sessionuser.UserID);
if (Success != 0)
{
//error
GenericMessage = "Something went wrong. Invalid Password.";
await this.GenericDialog.ShowAsync();
}
else
{
await this.DialogAddEditUser.HideAsync();
users = await UserService.UsersList();
this.StateHasChanged();
}
}
}
finally
{
isSubmitting = false;
}
}
//============== Account Combox Code on Change Combobox ===========================
public void OnChangeUserType(Syncfusion.Blazor.DropDowns.ChangeEventArgs<int, UserType> args)
{
SelectedUserTypeID = args.ItemData.UserTypeID; ;
this.AddEditUser.UserTypeID = args.ItemData.UserTypeID;
}
//Close AddEdit
private async Task CloseDialogAddEdit()
{
await this.DialogAddEditUser.HideAsync();
}
public void CustomizeCell(QueryCellInfoEventArgs<Users> args)
{
if (args.Column.Field == "Status")
{
if (args.Data.Status == "Active")
{
args.Cell.AddClass(new string[] { "active" });
}
else
{
args.Cell.AddClass(new string[] { "disabled" });
}
}
}
}
<style>
.active {
color: green !important;
}
.disabled {
color: red !important;
}
</style>
This is the effect I'm Getting.
Oliver
Hi Prathap Senthil,
I figured out why my QueryCellInfo wasn't working. I need to move it below other <GridEvents>.
<GridEvents OnToolbarClick="ToolbarClickHandler" TValue="UserModel"></GridEvents>
<GridEvents RowSelected="RowSelectHandler" OnToolbarClick="ToolbarClickHandler" TValue="UserModel"></GridEvents>
<GridEvents QueryCellInfo="CustomizeCell" TValue="UserModel"></GridEvents>
It now works. CSS is working finally. But it also introduced 2 (two) issues my OnToolbarClick="ToolbarClickHandler"
and RowSelected="RowSelectHandler" GridEvents are not working anymore. I'm I getting conflicts?
Oliver
Attaching a video regarding issue on grid events OnToolbarClick and RowSelected Grid Events not working if I move QueryCellInfo below them. If position the QueryCellInfo Grid event above the OnToolbarClick and RowSelected Grid event the QueryCellInfo Grid wont work.
I got it. Changed my code to this.
<GridEvents RowSelected="RowSelectHandler"
OnToolbarClick="ToolbarClickHandler"
QueryCellInfo="CustomizeCell"
TValue="UserModel"></GridEvents>
🤣
We are glad to hear that the reported issue has been resolved at your end. Please get back to us if you need further assistance. As always we will be happy to assist you.