I'm trying to use a combo in a grid as follows:
@(Html.Infragistics() .Grid(Model) .ID("grid1") .PrimaryKey(nameof(LuItemType.ItemTypeId)) .UpdateUrl(Url.Action("UpdatingSaveChanges", "ItemType")) .AutoGenerateLayouts(false) .AutoCommit(true) .Columns(column => { column.For(x => x.ItemDesc).HeaderText("Description").DataType("string"); column.For(x => x.SafeWorkingLoad).HeaderText("SWL").DataType("string"); column.For(x => x.InspectionPeriodId).HeaderText("InspectionPeriod"); }) .Width("600px") .Height("500px") .Features(features => { features.Updating() .EditMode(GridEditMode.Row) .EnableDeleteRow(true) .EnableAddRow(true) .ColumnSettings(settings => { settings.ColumnSetting().ColumnKey(nameof(LuItemType.ItemDesc)) .EditorType(ColumnEditorType.Text).Required(true).Validation(true); settings.ColumnSetting().ColumnKey(nameof(LuItemType.SafeWorkingLoad)) .EditorType(ColumnEditorType.Text).Required(true).Validation(true); settings.ColumnSetting().ColumnKey(nameof(LuItemType.InspectionPeriodId)) .EditorType(ColumnEditorType.Combo) .ComboEditorOptions(options => { options.DataSourceUrl(Url.Action("GetComboData", "ItemType")) .TextKey(nameof(LuInspectionPeriod.InspectionPeriodDesc)) .ValueKey(nameof(LuInspectionPeriod.InspectionPeriodId)) .Mode(ComboMode.DropDown); }) .Required(true).Validation(true); });
}) .DataSourceUrl(Url.Action("GetGridData", "ItemType")) .DataBind() .Render())
However, the combo isn't loaded with any data, so I'm seeing the Id of the row rather than the text description, and when I try to drop the list there's no data in it.The data source method is as follows:
public class ItemType : LookUpController<LuItemType> {
... SNIP ...
[ComboDataSourceAction] public ActionResult GetComboData() {return View(RsContext.LuInspectionPeriod.AsQueryable()); }
}
And the entity class looks like:
public partial class LuInspectionPeriod { public LuInspectionPeriod() { LiftingItem = new HashSet<LiftingItem>(); LuItemType = new HashSet<LuItemType>(); }
[Required] public int InspectionPeriodId { get; set; } [Required] public string InspectionDesc { get; set; } [Required] public int? InspectionPeriodDays { get; set; } [Required] public int? InspectionPeriodMonths { get; set; }
public virtual ICollection<LiftingItem> LiftingItem { get; set; } public virtual ICollection<LuItemType> LuItemType { get; set; } }
When I click on a the cell with the combo I get this error in the console:
jquery.js:9566 GET https://localhost:44307/ItemType/GetComboData?textKey=InspectionPeriodId&valueKey=InspectionPeriodId&toLower=1&_=1492017867793 500 (Internal Server Error)
Is there anything obviously wrong with how I've set this up?
In light of the answer on another question I've just added a column for the primary key column as follows:
@(Html.Infragistics() .Grid(Model) .ID("grid1") .PrimaryKey(nameof(LuItemType.ItemTypeId)) .UpdateUrl(Url.Action("UpdatingSaveChanges", "ItemType")) .AutoGenerateLayouts(false) .AutoCommit(true) .Columns(column => { column.For(x => x.ItemTypeId).HeaderText("ItemTypeId").DataType("string").Hidden(false); column.For(x => x.ItemDesc).HeaderText("Description").DataType("string"); column.For(x => x.SafeWorkingLoad).HeaderText("SWL").DataType("string"); column.For(x => x.InspectionPeriodId).HeaderText("InspectionPeriod"); }) .Width("600px") .Height("500px") .Features(features => { features.Updating() .EditMode(GridEditMode.Row) .EnableDeleteRow(true) .EnableAddRow(true) .ColumnSettings(settings => { settings.ColumnSetting().ColumnKey(nameof(LuItemType.ItemDesc)) .EditorType(ColumnEditorType.Text).Required(true).Validation(true); settings.ColumnSetting().ColumnKey(nameof(LuItemType.SafeWorkingLoad)) .EditorType(ColumnEditorType.Text).Required(true).Validation(true); settings.ColumnSetting().ColumnKey(nameof(LuItemType.InspectionPeriodId)) .EditorType(ColumnEditorType.Combo) .ComboEditorOptions(options => { options.DataSourceUrl(Url.Action("GetComboData", "ItemType")) .TextKey(nameof(LuInspectionPeriod.InspectionDesc)) .ValueKey(nameof(LuInspectionPeriod.InspectionPeriodId)) .Mode(ComboMode.DropDown); }) .Required(true).Validation(true); });
It's still not working, i.e. I can't edit the cells of any existing rows, and I can't drop the combo on the Add row, but I am getting a different error now:
Uncaught Error: The specified record or property was not found. Verify the criteria for your search and adjust them if necessary. at $.(anonymous function).(anonymous function)._getLatestValues (https://cdn-xat $.(anonymous function).(anonymous function)._getLatestValues (https://localhost:44307/lib/jquery-ui/jquery-ui.js:144:25) at $.(anonymous function).(anonymous function)._startEditForRow (https://cdn-na.infragistics.com/igniteui/2016.2/xxx/xxx/js/infragistics.lob.js:493:29009) at $.(anonymous function).(anonymous function)._startEditForRow (https://localhost:44307/lib/jquery-ui/jquery-ui.js:144:25) at $.(anonymous function).(anonymous function)._startEditForElement (https://cdn-na.infragistics.com/igniteui/2016.2/xxx/xxx/js/infragistics.lob.js:493:26680) at $.(anonymous function).(anonymous function)._startEditForElement (https://localhost:44307/lib/jquery-ui/jquery-ui.js:144:25) at $.(anonymous function).(anonymous function)._clickTrigger (https://cdn-na.infragistics.com/igniteui/2016.2/xxx/xxx/js/infragistics.lob.js:493:13512) at $.(anonymous function).(anonymous function)._clickTrigger (https://localhost:44307/lib/jquery-ui/jquery-ui.js:144:25) at HTMLTableCellElement.proxy (https://localhost:44307/lib/jquery/dist/jquery.js:496:14) at HTMLDivElement.dispatch (https://localhost:44307/lib/jquery/dist/jquery.js:5206:27)
Hello,
Thank you for using Infragistics forums!
The exception you receive is usually caused by improperly configured primary keys. Judging by the code you sent this is either caused by a mismatch between the PrimaryKey property and the key of the column it's supposed to be represented by (please, ensure nameof(LuItemType.ItemTypeId) returns "ItemTypeId" as that's the key for the column specified in the column collection) or by the PK not being resolvable by the schema generated for the model (it is generated from the column definitions). It could be helpful if you paste your GetGridData method so I can better understand what part of the entity the grid binds to. In any case these column definitions will expect an array of objects each having a property called "ItemTypeId" of type string. You can quickly check if the PK resolves correctly by using your browser's developer tools and inspecting one of the grid's rows. Each of them should have a data-id attribute with the same value as the record's ItemTypeId property.
I hope this helps!
Best regards,
Stamen Stoychev
So I've tried to get Martin's solution working as follows:
<script type="text/javascript">
$("#saveChanges").bind({ click: function () { $("#grid1").igGrid("saveChanges"); } });
fillProductNameLookup(lookupProductList);
function fillProductNameLookup(objectToFill) { var colSettings = $("#grid1").igGridUpdating("option", "columnSettings"); var colSetting; for (var i = 0; i < colSettings.length; i++) { colSetting = colSettings[i]; if (colSetting.columnKey === "InspectionPeriodId") { if (colSetting.editorType && colSetting.editorType === "combo") { var ds = colSetting.editorOptions.dataSource; var textKey = colSetting.editorOptions.textKey; var valueKey = colSetting.editorOptions.valueKey; var item; for (var j = 0; i < ds.length; i++) { item = ds[i]; objectToFill[item[valueKey]] = item[textKey]; } } break; } } }
var lookupProductList = {};
function lookupProductName(productNumber) { return lookupProductList[productNumber]; }</script>
The problem I'm having though is that fillProductNameLookup(lookupProductList) is trying to run before the grid is initialised. Currently I'm not using the loader (I'm using the CDN), but even if I was I don't know how I'd force this code to run after the mvc wrapper has completed? Is there a "grid initialized" event I can wrap the fillProductNameLookup(lookupProductList) call in?
The column then gets its data as follows:
column.For(x => x.InspectionPeriodId).HeaderText("InspectionPeriod").FormatterFunction("lookupProductName");
I am glad I was able to help. You can execute the function on the rendered event that you can subscribe to with the AddClientEvent method in the view.
Creating a lookup function to be executed for the column through a formatter is still the recommended approach. There is no automation that is available for this use case through the MVC wrappers.
Please, let me know if you have any other issues or have troubles implementing this solution!
Hi Stamen
I've tried to wire that in (as per code below), but it's not working because the datasource for the combo column is still empty at this point. I've put a break point in my GetComboData() and it isn't called until the combo is dropped down for the first time. Is there something I need to do to get it to eager load the data? I tried adding a DataBind call in the comboEditorOptions but that didn't help. Do you have an example of this that I could look at?
@(Html.Infragistics() .Grid(Model) .ID("grid1") .PrimaryKey(nameof(LuItemType.ItemTypeId)) .UpdateUrl(Url.Action("UpdatingSaveChanges", "ItemType")) .AutoGenerateLayouts(false) .AutoCommit(true) .Columns(column => { column.For(x => x.ItemTypeId).HeaderText("ItemTypeId").DataType("number").Hidden(true); column.For(x => x.ItemDesc).HeaderText("Description").DataType("string"); column.For(x => x.SafeWorkingLoad).HeaderText("SWL").DataType("string"); column.For(x => x.InspectionPeriodId).HeaderText("InspectionPeriod")/*.FormatterFunction("lookupProductName")*/; }) .Width("600px") .Height("500px") .Features(features => { features.Updating() .EditMode(GridEditMode.Row) .EnableDeleteRow(true) .EnableAddRow(true) .ColumnSettings(settings => { settings.ColumnSetting().ColumnKey(nameof(LuItemType.ItemDesc)) .EditorType(ColumnEditorType.Text).Required(true).Validation(true); settings.ColumnSetting().ColumnKey(nameof(LuItemType.SafeWorkingLoad)) .EditorType(ColumnEditorType.Text).Required(true).Validation(true); settings.ColumnSetting().ColumnKey(nameof(LuItemType.InspectionPeriodId)) .EditorType(ColumnEditorType.Combo) .ComboEditorOptions(options => { options.DataSourceUrl(Url.Action("GetComboData", "ItemType")) .TextKey(nameof(LuInspectionPeriod.InspectionDesc)) .ValueKey(nameof(LuInspectionPeriod.InspectionPeriodId)) .EnableClearButton(true) .Mode(ComboMode.DropDown); }) .Required(true).Validation(true);
});
features.Sorting().ColumnSettings(sorting => { sorting.ColumnSetting().ColumnKey(nameof(LuItemType.ItemDesc)) .CurrentSortDirection("ascending").AllowSorting(true); });
}) .AddClientEvent("rendered", "fillList()") .DataSourceUrl(Url.Action("GetGridData", "ItemType")) .DataBind() .Render())<br /><input type="button" class="btn btn-success" id="saveChanges" value="Save Changes" />
function fillList() { fillProductNameLookup(lookupProductList); }
// from https://ko.infragistics.com/community/forums/p/72892/370474.aspx#370474 function fillProductNameLookup(objectToFill) { var colSettings = $("#grid1").igGridUpdating("option", "columnSettings"); var colSetting; for (var i = 0; i < colSettings.length; i++) { colSetting = colSettings[i]; if (colSetting.columnKey === "InspectionPeriodId") { if (colSetting.editorType && colSetting.editorType === "combo") { var ds = colSetting.editorOptions.dataSource; var textKey = colSetting.editorOptions.textKey; var valueKey = colSetting.editorOptions.valueKey; var item; for (var j = 0; i < ds.length; i++) { item = ds[i]; objectToFill[item[valueKey]] = item[textKey]; } } break; } } }
Sorry, there's a typo above, the client event is now set up as .AddClientEvent("rendered", "fillList") but still doesn't work.