Megabit / Blazorise

Blazorise is a component library built on top of Blazor with support for CSS frameworks like Bootstrap, Tailwind, Bulma, AntDesign, and Material.
https://blazorise.com/
Other
3.25k stars 528 forks source link

conditionally style cells in a datagrid (or plain table)column #166

Closed githubfanster closed 5 years ago

githubfanster commented 5 years ago

hello! nice project!

we have a requirement to conditionally style the cells within a datagrid (or plain table) column to indicate, for example, different statuses. the styling would involve assigning color values to foreground and background colors depending on the results of some calculations involving a row model's properties. ideally, we'd like to be able to dynamically execute a function (or a lambda) to set these values as a row model's property values change.

using the weatherforecast data as example, if we have css classes in our site.css defined as:

.hot {
background-color: red;
color: white
}

.mild {
background-color: green;
color: black
}

how can we dynamically add / remove these css classes to a column cell, say, by executing code such:

protected Func<WeatherForecast, string> MyCssFunc = (WeatherForecast w) =>
{
    return w.TemperatureC > 14 ? "hot" : "mild";
};

could you please let me know if this is possible right now, and if yes, what's the recommended way of doing it for both the plain table as well as the new datagrid components?

(right now we are focused only on server-side blazor)

thank you so much for any help and tips!

stsrki commented 5 years ago

Yes you can use DisplayTemplate for custom styles in column cells. I'm not home now so I cannot write you code but you can see an example in the demo application. https://github.com/stsrki/Blazorise/blob/master/Tests/Blazorise.Demo/Pages/Tests/DataGridPage.razor

githubfanster commented 5 years ago

i'm not having success yet. please see below and let me know how to change DisplayTemplate. i've tried various combinations class, &@;class, Class, &@;Class -- all led to unrecognized exception thanks!

<DataGrid TItem="MatUnitDto"
          Data="@MatUnitDtos"
          EditMode="@editMode"
          AllowEdit="@allowEdit"
          AllowSort="@allowSort"
          AllowFilter="@allowFilter"
          ShowPager="@showPager"
          RowInserted="@OnRowInserted"
          RowUpdated="@OnRowUpdated"
          RowRemoved="@OnRowRemoved"
          UseInternalEditing="true"
          @bind-SelectedRow="@SelectedMatUnitDto">
    <DataGridCommandColumn TItem="MatUnitDto" />
    <DataGridColumn TItem="MatUnitDto" Field="@nameof(MatUnitDto.MatUnitCode)" Caption="Code" AllowSort="true" AllowEdit="true" />
    <DataGridColumn TItem="MatUnitDto" Field="@nameof(MatUnitDto.MatUnitDesc)" Caption="Description" AllowEdit="true" />
    <DataGridCheckColumn TItem="MatUnitDto" Field="@nameof(MatUnitDto.HasDecimal)" Caption="HasDecimal" AllowEdit="true"  AllowFilter="false">
        <DisplayTemplate @Class="@MyCssFunc(MatUnitDto)">
            @((context as MatUnitDto).HasDecimal ? "YES" : "NO")
        </DisplayTemplate>
    </DataGridCheckColumn>
</DataGrid>

and the code

@code {
    DataGridEditMode editMode = DataGridEditMode.Form;
    bool allowEdit = true;
    bool allowSort = true;
    bool allowFilter = true;
    bool showPager = true;

    [Parameter] List<MatUnitDto> MatUnitDtos { get; set; }
    [Parameter] MatUnitDto SelectedMatUnitDto { get; set; }

    protected override async Task OnInitAsync()
    {
        MatUnitDtos = await _mediator.Send(new MatUnitsAllQuery());
    }

    protected Func<MatUnitDto, string> MyCssFunc = (MatUnitDto m) =>
    {
        return m.HasDecimal ? "hot" : "mild";
    };
//skip for brevity
}
stsrki commented 5 years ago

<DisplayTemplate> can't have any attributes because it is a render fragment. see

Try this instead

<DataGridCheckColumn TItem="MatUnitDto" Field="@nameof(MatUnitDto.HasDecimal)" Caption="HasDecimal" AllowEdit="true" AllowFilter="false">
    <DisplayTemplate>
        @{
            var matUnit = ( context as MatUnitDto );

            if ( matUnit.HasDecimal )
            {
                <label class="hot"><span>YES</span></label>
            }
            else
            {
                <label class="mild"><span>NO</span></label>
            }
        }
    </DisplayTemplate>
</DataGridCheckColumn>
githubfanster commented 5 years ago

that worked! thanks! i see that even though i have a DisplayTemplate, i dont necessarily have to have it paired with a custom EditTemplate if the "default" or built-in "template" would work fine. can u please confirm for sure? thanks again!

stsrki commented 5 years ago

That's right. Default is always used if Display or Edit template are not used.

githubfanster commented 5 years ago

also, is DisplayTemplate available in the DataGrid only and not other Blazorise components?

stsrki commented 5 years ago

DisplayTemplate and EditTemplate are just that, the templates. You can basically place anything in them. The preferred are Blazorise components but you can do whatever you want and need based on your project specifics.

githubfanster commented 5 years ago

ok. thanks! closing this now ...