Field not updating when using dropdown list in Grid

Hi,

After updating to 18.2.46, data coming into Grid from dropdown list is not updated. Please consider the following code:

     <GridColumn Field=@nameof(People.Id) HeaderText="Id" IsPrimaryKey="true" IsIdentity="true" AllowEditing="false" Visible="false" ShowInColumnChooser="false"></GridColumn>
<GridColumn Field=@nameof(People.PersonSalutation) HeaderText="Saludo" Visible="true" AutoFit="true">
<Template>
@{
var peopleContext = context as People;
if (@peopleContext.PersonSalutationNavigation != null) {
<span>@peopleContext.PersonSalutationNavigation.SalutationShort</span>
}
}
</Template>
<EditTemplate>
Saludo
<SfDropDownList ID="PersonSalutation" TItem="Salutations" TValue="string" Placeholder="Saludo" Index="@salutationIndex">
<SfDataManager Url=@($"{apiURL}/salutations") Adaptor="Adaptors.ODataV4Adaptor" CrossDomain="true" Offline="true"></SfDataManager>
<DropDownListFieldSettings Value="Id" Text="SalutationShort"></DropDownListFieldSettings>
</SfDropDownList>
</EditTemplate>
</GridColumn>

I understood that the ID parameter in DropDownList makes the relation to the parent field in the datagrid. I looked at the OData request sent from grid and is not updating the information.

Did something change from previous 18.1 versions?

Regards,

Erick




11 Replies 1 reply marked as answer

VN Vignesh Natarajan Syncfusion Team July 27, 2020 05:18 PM UTC

Hi Erick,  
 
Thanks for contacting Syncfusion support.  
 
Query: “data coming into Grid from dropdown list is not updated. 
 
We have validated the reported query and from your code example we found that you have not defined the Value property for the components (SfDropDownList) in the EditTemplate. From our 2020 Volume 2 release, components inside the EditTemplate must be defined with two binding for Value property to save the changes in Grid properly. So kindly define the @bind-Value property to DropDownList component to save the changes properly in Grid. 
 
Refer our UG documentation for your reference 
 

Kindly get back to us if you have further queries.    
 
Regards, 
Vignesh Natarajan 


Marked as answer

ER Erick July 30, 2020 01:51 AM UTC

Thank you very much. That solved my problem.


VN Vignesh Natarajan Syncfusion Team July 30, 2020 05:59 AM UTC

Hi Erick,  

Thanks for the update.  

We are glad to hear that you resolved your query using our solution.  

Kindly get back to us if you have further queries.  

Regards,
Vignesh Natarajan 




ER Erick August 1, 2020 05:56 AM UTC

Hello,

I have noticed another problem when using @bind-Value for SfDropdown inside SfGrid. If the value for dropdown is nullable in the database, the Add operation is not possible (Save button of Edit Form does not work - makes no action at all and does not throw any exception). It works without selecting any value for dropdown (null) and then editing the row and changing dropdown value to desired value.

When dropdown value variable is of type not null (in the database and model), the application throws an exception when pressing the toolbar Add button, as follows:

warn: Microsoft.AspNetCore.Components.Server.Circuits.RemoteRenderer[100]
      Unhandled exception rendering component: Object reference not set to an instance of an object.
System.NullReferenceException: Object reference not set to an instance of an object.
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.getItemData()
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.setValue()
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.updateValues(Dictionary`2 props)
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.initValue(Dictionary`2 props)
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.InitialRendered()
   at Syncfusion.Blazor.BaseComponent.InitComponent()
   at Syncfusion.Blazor.BaseComponent.OnAfterRenderAsync(Boolean firstRender)
   at Syncfusion.Blazor.DropDowns.DropDownBase`1.OnAfterRenderAsync(Boolean firstRender)
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.OnHybridAfterRender(Boolean firstRender)
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.OnAfterRenderAsync(Boolean firstRender)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)
fail: Microsoft.AspNetCore.Components.Server.Circuits.CircuitHost[111]
      Unhandled exception in circuit 'vIxcqAc-D7U9cS5jcS07GhmxqgXDoyTqFaGr5BfOoGs'.
System.NullReferenceException: Object reference not set to an instance of an object.
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.getItemData()
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.setValue()
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.updateValues(Dictionary`2 props)
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.initValue(Dictionary`2 props)
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.InitialRendered()
   at Syncfusion.Blazor.BaseComponent.InitComponent()
   at Syncfusion.Blazor.BaseComponent.OnAfterRenderAsync(Boolean firstRender)
   at Syncfusion.Blazor.DropDowns.DropDownBase`1.OnAfterRenderAsync(Boolean firstRender)
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.OnHybridAfterRender(Boolean firstRender)
   at Syncfusion.Blazor.DropDowns.SfDropDownList`2.OnAfterRenderAsync(Boolean firstRender)
   at Microsoft.AspNetCore.Components.RenderTree.Renderer.GetErrorHandledTask(Task taskToHandle)

The Grid is as follows:

<SfGrid @ref="Grid" TValue="Stores" Query="@GridQuery" AllowPaging="true" AllowSorting="true" AllowReordering="false"
AllowResizing="true" AllowFiltering="false" AllowGrouping="false" ShowColumnChooser="false" Toolbar="@Tool">
<GridEvents OnActionBegin="ActionBeginHandler" TValue="Stores"></GridEvents>
<SfDataManager Url=@($"{apiURL}/stores") Adaptor="Adaptors.ODataV4Adaptor" CrossDomain="true"></SfDataManager>
<GridEditSettings AllowAdding="true" AllowEditing="true" AllowDeleting="true" ShowDeleteConfirmDialog="true" Mode="EditMode.Dialog">
<HeaderTemplate>
@{
var text = GetHeader((context as Stores));
<span>@text</span>
}
</HeaderTemplate>
</GridEditSettings>
<GridColumns>
<GridColumn Field=@nameof(Stores.Id) HeaderText="Id" IsPrimaryKey="true" IsIdentity="true" AllowEditing="false" Visible="false" ShowInColumnChooser="false"></GridColumn>
<GridColumn Field=@nameof(Stores.StoreId) HeaderText="Identificación" AutoFit="true"></GridColumn>
<GridColumn Field=@nameof(Stores.StoreShortName) HeaderText="Nombre Corto" AutoFit="true"></GridColumn>
<GridColumn Field=@nameof(Stores.StoreFullName) HeaderText="Nombre" AutoFit="true"></GridColumn>
<GridColumn Field=@nameof(Stores.StoreIp) HeaderText="IP" AutoFit="true"></GridColumn>
<GridColumn Field=@nameof(Stores.StoreFtpUser) HeaderText="Usuario" AutoFit="true"></GridColumn>
<GridColumn Field=@nameof(Stores.StoreFtpPassword) HeaderText="Password" AutoFit="true"></GridColumn>
<GridColumn Field=@nameof(Stores.DivsId) HeaderText="División" AutoFit="true">
<Template>
@{
var storeContext = (context as Stores);
if (storeContext.Divs != null)
{
<span>@storeContext.Divs.DivName</span>
}
}
</Template>
<EditTemplate>
<span>División</span>
<SfDropDownList ID="DivsId" @bind-Value="@((context as Stores).DivsId)" TItem="Divs" TValue="int" Placeholder="División">
<SfDataManager Url=@($"{apiURL}/divs") Adaptor="Adaptors.ODataV4Adaptor" CrossDomain="true" Offline="true"></SfDataManager>
<DropDownListFieldSettings Value="Id" Text="DivName"></DropDownListFieldSettings>
</SfDropDownList>
</EditTemplate>
</GridColumn>
</GridColumns>
</SfGrid>

Regards,

Erick





VN Vignesh Natarajan Syncfusion Team August 3, 2020 02:21 PM UTC

Hi Erick,  
 
Query: “I have noticed another problem when using @bind-Value for SfDropdown inside SfGrid 
 
We understand that you are facing issue with DropDownList components inside the Grid EditTemplate with Text and Value pair. The reported issue occur at our end, only when dropdownlist datasource has null values in it (where its TValue is defined as int). If you are facing similar issue then kindly define the TValue of DropDownList as int? to resolve the issue. The reported issue might also occur when type of DivsId property from Stores class differ with type of Id property from Divs class.  
 
Kindly ensure that both these properties (DivsId and its foreignkey property Id) are of same type. Once resolving this issue, we are suspect you are facing issue while inserting a record in Grid. So kindly share the following details to validate the reported issue at our end.  
 
  1. Share the model classes of the both Stores and Divs along with its properties.
  2. Share the error details you are facing while adding a record in Grid by defining OnActionFailure event of Grid.
  1. Share the video demonstration of the issue with a replication procedure.
 
Above requested details will be helpful for us to validate the reported issue at our end and provide solution as early as possible.  
 
Regards, 
Vignesh Natarajan 



ER Erick August 4, 2020 03:00 AM UTC

Hi Vignesh,

Thank you for your prompt response.

1. These are the model classes for Stores and Divs:

public partial class Stores
{
public Stores()
{
TrxHeaders = new HashSet<TrxHeaders>();
}

[Key]
public int Id { get; set; }
[Required]
[Column("Store_Id")]
[StringLength(10)]
public string StoreId { get; set; }
[Required]
[Column("Store_Short_Name")]
[StringLength(30)]
public string StoreShortName { get; set; }
[Required]
[Column("Store_Full_Name")]
[StringLength(60)]
public string StoreFullName { get; set; }
[Required]
[Column("Store_IP")]
[StringLength(55)]
public string StoreIp { get; set; }
[Column("Store_FTP_User")]
[StringLength(50)]
public string StoreFtpUser { get; set; }
[Column("Store_FTP_Password")]
[StringLength(50)]
public string StoreFtpPassword { get; set; }
[Column("DIVs_Id")]
public int DivsId { get; set; }

[ForeignKey(nameof(DivsId))]
[InverseProperty("Stores")]
public virtual Divs Divs { get; set; }
[InverseProperty("TrxHeaderStoreNavigation")]
public virtual ICollection<TrxHeaders> TrxHeaders { get; set; }
}

[Table("DIVs")]
public partial class Divs
{
public Divs()
{
Stores = new HashSet<Stores>();
}

[Key]
public int Id { get; set; }
[Required]
[Column("DIV_ID")]
[StringLength(6)]
public string DivId { get; set; }
[Required]
[Column("DIV_NAME")]
[StringLength(60)]
public string DivName { get; set; }
[Column("DIV_LOGO")]
public byte[] DivLogo { get; set; }

[InverseProperty("Divs")]
public virtual ICollection<Stores> Stores { get; set; }
}

2. I added OnActionFailure event to the Grid, but it never gets there. The exception is thrown before (at SfDropDownList level)

3. I'm attaching two videos. One for the scenario with public int DivsId { get; set; } (id not null) and other with public int? DivsId { get; set; }  (id nullable). In the first case the exception is thrown when clicking on Add in the Grid. In the second case there is no exception thrown; I can add a store without Div (store division) association (can be added with edit later), but cannot add a store when selecting a Div (the app hangs without any error)

As additional comment, this only happens when I use OData in SfDropDownList. If I get the list, for example, calling the api inside OnInitializedAsync, assigning the result to an IEnumerable, and using that variable as the data source for SfDropDownList, it works. The problem with that solutions is that for editing, I need to pass an Index parameter to the dropdown in order to have the current value (which is too slow when having several dropdowns in a grid - because the need of one api call for getting the list and the generation of the index)

Thanks a lot for looking at this.

Erick







Attachment: Dropdown_in_Grid_ddbfd82c.zip


VN Vignesh Natarajan Syncfusion Team August 5, 2020 01:51 PM UTC

Hi Erick, 
 
Thanks for sharing the requested details.  
 
Query: “In the first case the exception is thrown when clicking on Add in the Grid. 
 
We have analyzed the provided video demo and we have validated the reported query by preparing a sample using your code example and model class properties (only with primarykey and foreignkey properties). We are unable to reproduce the reported issue at our end. Kindly download the sample which we have prepared using 18.2.0.48 version from below  
 
 
Note: Run the sample with OData.API and OData.UI as startup project. Also change the json file location in both the controllers.  
 
Also we would like to inform you that instead of using Column Template and Edit Template to bind the column with ForeignKey behavior. We suggest you to use ForeignKey Column feature of Grid to render column with ForeignKey behavior in Grid. Refer our UG documentation for your reference. In this case ( for ForeignKey Column) default EditType will be DropDownList hence external EditTemplate is not necessary.  
 
 
If you are still facing the issue kindly share the following details which will be helpful for us to validate the reported issue at our end.  
 
  1. Share your Syncfusion.Blazor Nuget package version.
  2. Kindly ensure the reported issue by removing the complex properties from Orders class
[ForeignKey(nameof(DivsId))] 
        [InverseProperty("Stores")] 
        public virtual Divs Divs { get; set; } 
        [InverseProperty("TrxHeaderStoreNavigation")] 
        public virtual ICollection<TrxHeaders> TrxHeaders { get; set; } 
 
 
  1. If possible try to reproduce the reported issue in provided sample and revert back to us.   
    
Issue reproducible sample will be helpful for us to validate the reported issue at our end and provide solution as soon as possible.  
 
Regards, 
Vignesh Natarajan 



ER Erick August 7, 2020 01:23 AM UTC

Hello Vignesh,

Thanks for your response. I was using 18.1.0.59 (because some issues with 18.2.0.47). However, with the upgrade to 18.2.0.48 everything works fine (without code modification)

I also changed the code as recommended (to use ForeignKeyColumn instead Template and EditTemplate)

<GridForeignColumn Field=@nameof(Stores.DivsId) HeaderText="División" TValue="Divs" ForeignKeyField="Id" ForeignKeyValue="DivName" AutoFit="true">
<SfDataManager Url=@($"{apiURL}/divs") Adaptor="Adaptors.ODataV4Adaptor" CrossDomain="true"></SfDataManager>
</GridForeignColumn>

It also works with a small caveat that I'm not able to sort out. As you might have seen in my model, one item in the Stores table has a div (division) associated, that gets from the Divs table. When editing a store, the div dropdown (the ForeignColumn) only shows currently used values in stores table. I discovered this because in the test database I only have two stores (with divs 1 and 2) and in the Divs table I have three records.


On the edit dialog:


On the Divs database




Is there any option to show all options available in the database?

Thanks,

erick







JP Jeevakanth Palaniappan Syncfusion Team August 7, 2020 03:08 PM UTC

Hi Erick, 
 
We have validated your query and we found that you need to bind different datasource for dropdown in edit form while performing edit action. We suggest you to use the EditorSettings of the GridForeignColumn to achieve your requirement. Please refer the below code example for your reference. 
 
<GridForeignColumn TValue="EmployeeData" EditorSettings ="@EmployeeEditParams" Field=@nameof(Order.EmployeeID) HeaderText="Employee Name" ForeignKeyValue="FirstName" Width="150"> 
            <Syncfusion.Blazor.Data.SfDataManager Url="https://js.syncfusion.com/demos/ejServices/Wcf/Northwind.svc/Employees" CrossDomain="true" Adaptor="Adaptors.ODataAdaptor"> 
            </Syncfusion.Blazor.Data.SfDataManager> 
</GridForeignColumn> 
 
@code{ 
 
//Instead of Country we suggest you to set your Custom DataSource 
 
public IEditorSettings EmployeeEditParams = new DropDownEditCellParams 
{ 
    Params = new DropDownListModel<object, object>() { DataSource = Country } 
}; 
 
} 
 
Please get back to use if you need further assistance. 
 
Regards, 
Jeevakanth SP. 



ER Erick August 9, 2020 03:47 AM UTC

Thanks Jeevakanth,

From your example, I populated the DataSource param as follows (it works ok):

public IEditorSettings PersonSalutationEditParams { get; set; }

protected override async Task OnInitializedAsync()
{
await base.OnInitializedAsync();
PersonSalutationEditParams = new DropDownEditCellParams
{
Params = new DropDownListModel<object, object>() { DataSource = (IEnumerable<Salutations>)(await XARetailAPIService.GetSalutations()).SalutationsList }
};
}

I was wondering if this is the correct way to do it? What happens if the returned list is too big? Is there another way to bind dynamic retrieval as needed from the api call (OData)?

Regards,

Erick




VN Vignesh Natarajan Syncfusion Team August 10, 2020 06:20 AM UTC

Hi Erick,  
 
Sorry for the inconvenience caused.  
 
Query: “Is there any option to show all options available in the database? && What happens if the returned list is too big? Is there another way to bind dynamic retrieval as needed from the api call (OData)? 
 
We have validated your query and we are able to reproduce the reported issue “Dropdownlist for foreignkey column does not show all the options from database in its list” at our end. We have already logged an defect report “While editing a foreign key column, editor is not displayedrelated to default editors for ForeignKey Column. We will also ensure your scenario while fixing the reported issue. Thank you for taking the time to report this issue and helping us improve our product. At Syncfusion, we are committed to fixing all validated defects (subject to technological feasibility and Product Development Life Cycle ) and including the defect fix in weekly patch release which is expected to be rolled out by mid of September 2020.     
    
You can now track the current status of your request, review the proposed resolution timeline, and contact us for any further inquiries through this link.    
 
 
Note: Kindly login in to view the feedback.   
 
Till then we suggest you to bind the datasource externally to DropDownList using EditorSettings as a workaround.  
 
Regards, 
Vignesh Natarajan 


Loader.
Up arrow icon