I have a grid column like
```
<GridColumn Field=@nameof(SchoolDto.DepartmentNumber) HeaderText="Department #">
<EditTemplate>
@{
var school = (context as SchoolDto);
<select class="form-select select2-departmentnumber" aria-required="true"
data-placeholder="-- Select DepartmentNumber --">
@if (school!.DepartmentNumber > 0)
{
<option value="@school!.DepartmentNumber" selected="selected">@school!.DepartmentNumber</option>
}
</select>
}
</EditTemplate>
</GridColumn>
```
How would I bind the value selected in the select to school.DepartmentNumber.
Also I want this to be a select2. The problem is that on page load the select is not in the DOM so calling any JS will not detect it. The select only appears on editing. When would be a good time to call the JS to turn the select into a select2. In which event.
Hi Wuss,
Based on the reported
problem, we would like to clarify that the grid edit template feature will be
performed when a row is in editing state. This is the default behavior. If you
want to call a function at the appropriate time in JavaScript, we suggest using
the Databound
event to achieve your requirement. Alternatively, if you want to perform
the same operation during initialization, we suggest using the Column
template feature to apply the same code as you did in the edit template to
achieve your requirement.
Regards,
Prathap S
Thanks for your reply. I was able to solve the 2nd part of the issue by running a JS script each time "BeginEdit" and "Add" action were fired in "OnGridActionBegin". The JS started a "MutationObserver" that watched for the appearance of the "select" and applied the "select2" features to it when it became available.
I am still having an issue with Part1 of the question binding
<GridColumn Field=@nameof(SchoolDto.DepartmentNumber) HeaderText="Department #">
<EditTemplate>
<select @bind="((context as SchoolDto)!.DepartmentNumber)" class="form-select select2-departmentnumber" aria-required="true"
data-placeholder="-- Select Department # --">
@if (context is not null && (context as SchoolDto).DepartmentNumber > 0)
{
<option value="@((context as SchoolDto).DepartmentNumber)" selected="selected">
@((context as SchoolDto).DepartmentNumber)
</option>
}
</select>
</EditTemplate>
</GridColumn>
When i try to bind to the context the original value in that field is retained it does not update to the value i selected in the select. That is for updating. If I add it says no value was selected as i have that field as a required field. I can see the value visually was selected but for some reason it thinks no value is there.
Before proceeding with the reporting of the problem, we require some additional clarification from your end. Please share the following details to proceed further on our end:
The details requested above will be very helpful in validating the reported query on our end and providing a solution as soon as possible. Thanks for your understanding.
Additionally, we have
support for the Syncfusion dropdown
component using the in-grid edit template. Please refer to this
documentation for more information.
Hi there, I have attached a demo. I took the liberty of adding two more more issues that I would have posted separately in the demo.
#1
Launch project and navigate to Products link. The grid will load. Try to add a product. It's not possible.
Try to edit a product by changing the category. After record is saved it saves with old value and not new value.
#2
On the same product pages The category Id is displayed instead of the category name. Seems I can't use Navigation property in the grid column?
#3
Open the category page and you will see that it results in a 401 when using webapi adaptor. The route it is trying to access has an [Authorize] annotation. Auth/Authz is done with built in identity cookies. It's difficult to find how to set up with the grid to send cookies.
Nuget Packages
<PackageReference Include="Syncfusion.Blazor.Grid" Version="25.1.35" />
<PackageReference Include="Syncfusion.Blazor.Themes" Version="25.1.35" />
Thanks.
Attachment: DemoAuth_a408a3f8.zip
Regarding
the first query, it appears that the primary key is not provided when
performing the add operation. The CRUD operation requires the presence of a
primary key to execute. Therefore, please ensure that the primary key is
included when inserting records. Refer the below code snippet and documentation
for your reference,
|
<GridColumn Field=@nameof(Product.Id) HeaderText="Id" IsPrimaryKey="true" Visible="true" /> |
Note: If you wish to hide the primary key column, please enable the
'IsIdentify' property in the grid column and ensure the same on the database
side. Refer to the documentation
provided for further details.
API Link: https://help.syncfusion.com/cr/blazor/Syncfusion.Blazor.Grids.GridColumn.html#Syncfusion_Blazor_Grids_GridColumn_IsIdentity
Regarding the second query, it
seems that you have bound the category ID, and the grid displays based on the
field property defined in the grid column. This behavior is default for the
grid. If you wish to display the category name using the column template
feature to meet your requirements, you can achieve this by referring to the
code snippet below. Similar to this example, you can customize the behavior to
meet your specific needs.
|
<Template> @{ var data = context as Product; if(data.CategoryId == 1) { <span>Electronics</span> } if (data.CategoryId == 2) { <span>Clothing</span> } if (data.CategoryId == 3) { <span>Produce</span> }
} </Template> |
Regarding the third query, we have
already documented the scenario. Kindly refer to the documentation below for
your reference.
https://blazor.syncfusion.com/documentation/datagrid/data-binding#authorization-and-authentication
I figured out #2 above. I just needed to use "Field="NavigationProperty.Property" instead of "Field=@nameof(Value.NavigationProperty.Property)" in my specific case
<GridColumn Field="Category.Name" HeaderText="Category">
#1 enabling IsIdentity does not work, I believe I already had IsPrimaryKey enabled, and even making it visible did not work. Did you try it from your end and it worked?
#3 still an issue as your documentation refers to bearer tokens, I am using the default Identity cookies for auth/authz. Is that supported?
Regarding the issue with the add operation, we suggest using the AutoComplete component according to your requirements. This will facilitate achieving your desired functionality with proper add operations in the grid. Please refer to the modified code snippet and sample provided below for your reference.
|
<GridColumn Field=@nameof(Product.CategoryId) HeaderText="Category">
<EditTemplate> <SfAutoComplete ID="CategoryId" Placeholder="Select Category please type number" TItem="Category" TValue="int" @bind-Value="@((context as Product).CategoryId)" DataSource="@Categories"> <AutoCompleteFieldSettings Value="id" Text="Name"></AutoCompleteFieldSettings> </SfAutoComplete> </EditTemplate> </GridColumn> |
Are you experiencing any issues
with bearer tokens? Could you please share with us the specific problem you
encountered with the replication sample.
1.
"we
suggest using the AutoComplete component according to your requirements."
The reason I selected Select2 is that it supports filter and paging (not virtualization) from the server side.
That is as you type or scroll it fetches a set amount from the server directly without downloading the entire table.
Is this supported in sfautocomplete or sfdropdownlist, I could not find any documentation to let me know this. Serverside paging and filtering are the requirements here.
2.
The application is using cookies for authentication. To introduce bearer tokens would mean having two different auth mechanisms. Does it mean I have to strip out cookies auth and replace with a bearer token type of auth?
I have set up a JS action to read the current select2 value
and this additional grid action
private async void OnGridActionBegin(ActionEventArgs<SchoolDto> args)
{
if (args.RequestType.Equals(Syncfusion.Blazor.Grids.Action.Save))
{
var select2Selection = await _jsruntime.InvokeAsync<string>("blazorInterop.Select2GetValue",
"select2-departmentnumber");
if (int.TryParse(select2Selection, out int departmentNumber))
{
args.Data = args.Data with { DepartmentNumber = departmentNumber };
Console.WriteLine(args.Data);
}
}
}
I can see the correct currently selected value is retireved and I can see that the object is correctly updated in the action, But it is being done AFTER sending the request to update the info. I can't tell where would be the proper place to update args.Data before request is sent to update grid. I thought it would be in the save action.
It seems having an await statement in the OnActionBegin handler when a save occurs is not waiting on the await, but instead proceeding to send the request. It seems like a bug.
1.Yes, you
can filter the data from the server side by changing the query property
dynamically when using remote data, or else manually request the server when
custom filtering is used. Can you please share the use case scenario for paging
support and specify whether you want a remote datasource or local
datasource?"
Reference: Syncfusion documentation on Autocomplete virtualization
2.Yes,
migrating to bearer tokens entails replacing cookie-based authentication with a
token-based system, consolidating authentication mechanisms.
Regarding your last update, we suggest resolving this problem by using Async
Task
private async Task OnGridActionBegin(ActionEventArgs<SchoolDto> args) |
Wow regarding the async bit I forgot to change the void to Task that you pointed out above! THANK YOU!
We are glad to hear that the reported issue resolved at your end. Kindly get back to us if you have further queries. As always we will be happy to assist you.
Finally figured out how to make syncfucion grid work with auth cookies.
if using blazor .net8 or greater , I did this
...
...
builder.Services.AddHttpClient(
"MyApp",
client => client.BaseAddress = new Uri(builder.Configuration.GetSection("AppUrls")["BaseApiUrl"]!)
).AddHeaderPropagation() // <--- THIS LINE MUST BE ADDED
.ConfigurePrimaryHttpMessageHandler(() =>
{
// !!! DISABLE IN PROD. THIS IS TO BYPASS CHECKING SSL CERT AUTH FOR DEV PURPOSES !!!
var handler = new HttpClientHandler
{
ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator
};
return handler;
});
builder.Services.AddHeaderPropagation(options => // <-- THIS BLOCK MUST BE ADDED
{
options.Headers.Add("Cookie"); <--- THE HEADER FOR ME WAS "Cookie"
});
...
...
app.UseHttpsRedirection();
app.UseHeaderPropagation(); //<--- MUST BE ADDED, place after app.UseHttpsRedirection()
...
...
Thanks for the update,
We are happy to hear that the issue you reported has been resolved at your end. We are closing the thread now.