Hello everyone,
Due to a lack of shared examples and scenarios about the discussed built-in functionality, we decided to close the item as completed with the following knowledge base article that uses the approach of my colleague Yanislav: Allow or Prevent Selection of Certain Rows in the Grid
Regards,
Tsvetomir
Progress Telerik
Hello Everyone,
Thank you for your feedback on our product!
I'd like to understand more about your use cases for this feature and why it is needed. While we recognize its validity, the described requirement can typically be achieved without introducing additional built-in functionality.
Essentially, you can listen for the SelectedItemsChanged event of the Grid and prevent the selection of items conditionally.
<TelerikGrid Data="@MyData"
SelectedItems="@SelectedItems"
SelectedItemsChanged="@((IEnumerable<SampleData> items) => SelectedItemsChanged(items))"
...
public void SelectedItemsChanged(IEnumerable<SampleData> items)
{
SelectedItems = items.Where(x => x.Selectable).ToList();
}
As for the checkboxes, you can disable them by conditionally applying classes to the rows in which the checkboxes should be disabled.
<TelerikGrid Data="@MyData"
...
OnRowRender="@OnRowRenderHandler">
void OnRowRenderHandler(GridRowRenderEventArgs args)
{
var item = args.Item as SampleData;
if (!item.Selectable)
{
args.Class = "unselectable-row";
}
}
This way, you can add a CSS rule that targets those checkboxes within the rows with the applied custom class and disable them.
<style>
.unselectable-row > td .k-checkbox {
opacity: 0.5;
pointer-events: none;
}
</style>
Here is a REPL example that demonstrates this approach: https://blazorrepl.telerik.com/QoOIbJPG46vdHcQw12
Would you mind reviewing the example and sharing some scenarios (if there are any) where having such built-in functionality would be particularly useful, and in which the approach suggested above would not suffice?
This information will help us determine whether or not to include this feature in our API. If it turns out that this functionality can be achieved with CSS, we may decide not to include it to preserve the API clear. However, we'd still like to hear more about your specific needs before making a final decision.
Thank you for taking the time to share your thoughts with us.
Regards,
Yanislav
Progress Telerik
You may also find interesting this idea: https://feedback.telerik.com/blazor/1454469-select-rows-only-with-checkboxes-clicking-the-rows-to-not-affect-selection
Regards,
Marin Bratanov
Progress Telerik
Marin,
Thanks for the quick and detailed response
Hi Jeffrey,
This post will list three ideas I can offer for this, and it is a bit long. I have ordered them from least to most amount of code you'd need to write (which has an inverse relationship to the flexibility you can achieve).
For the time being you can handle the selection change event and loop the selected items, and take only those you want (which is not ideal, of course): https://docs.telerik.com/blazor-ui/components/grid/selection/multiple#selecteditemschanged-event.
Another option (which, in my opinion has slightly worse UX) is to use two-way binding for the selected items and only store the ones you want. The issue is that the checkbox will stay toggled even if the item does not get selected:
<TelerikGrid Data=@GridData
SelectionMode="GridSelectionMode.Multiple"
@bind-SelectedItems="SelectedItems"
Pageable="true"
Height="400px">
<GridColumns>
<GridCheckboxColumn />
<GridColumn Field=@nameof(Employee.Name) />
<GridColumn Field=@nameof(Employee.Team) Title="Team" />
</GridColumns>
</TelerikGrid>
@if (SelectedItems != null)
{
<ul>
@foreach (Employee employee in SelectedItems)
{
<li>
@employee.Name
</li>
}
</ul>
}
@code {
public List<Employee> GridData { get; set; }
IEnumerable<Employee> _selItems { get; set; }
public IEnumerable<Employee> SelectedItems {
get
{
return _selItems;
}
set
{
_selItems = value.Where(empl => empl.EmployeeId != 2);
}
}
protected override void OnInitialized()
{
GridData = new List<Employee>();
for (int i = 0; i < 15; i++)
{
GridData.Add(new Employee()
{
EmployeeId = i,
Name = "Employee " + i.ToString(),
Team = "Team " + i % 3
});
}
// select Employee with 3 through 5
SelectedItems = GridData.Skip(2).Take(3).ToList();
}
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Team { get; set; }
}
}
A third option is to implement the selection with your own code and disabled checkboxes in the column template, something like this:
<TelerikGrid Data=@GridData
SelectionMode="GridSelectionMode.None"
Pageable="true"
Height="400px">
<GridColumns>
<GridColumn Field="@(nameof(Employee.EmployeeId))">
<Template>
@{
Employee empl = context as Employee;
<input type="checkbox" id="@("selCb_" + empl.EmployeeId)" class="k-checkbox" checked="@empl.Selected"
@onchange="@(e => SelectEmployee(empl, e))" @key="@empl.EmployeeId" disabled="@( empl.EmployeeId == 3 )" />
<label class="k-checkbox-label" for="@("selCb_" + empl.EmployeeId)">Select @empl.EmployeeId</label>
}
</Template>
</GridColumn>
<GridColumn Field=@nameof(Employee.Name) />
<GridColumn Field=@nameof(Employee.Team) Title="Team" />
</GridColumns>
</TelerikGrid>
@if (SelectedItems.Count > 0)
{
<ul>
@foreach (Employee employee in SelectedItems)
{
<li>
@employee.Name
</li>
}
</ul>
}
@code {
public List<Employee> GridData { get; set; }
public List<Employee> SelectedItems { get; set; } = new List<Employee>();
void SelectEmployee(Employee emplToSelect, ChangeEventArgs e)
{
bool isSelected = bool.Parse(e.Value.ToString());
emplToSelect.Selected = isSelected;
if(isSelected)
{
SelectedItems.Add(emplToSelect);
}
else
{
SelectedItems.Remove(emplToSelect);
}
}
protected override void OnInitialized()
{
GridData = new List<Employee>();
for (int i = 0; i < 15; i++)
{
GridData.Add(new Employee()
{
EmployeeId = i,
Name = "Employee " + i.ToString(),
Team = "Team " + i % 3
});
}
}
public class Employee
{
public int EmployeeId { get; set; }
public string Name { get; set; }
public string Team { get; set; }
public bool Selected { get; set; }
}
}
Regards,
Marin Bratanov
Progress Telerik