I am dynamically adding columns to a grid because I don't know the names of all the columns until runtime. That worked great until I needed to turn on filtering. There will be four preset views that will filter the data rows, showing and hiding rows based on the definition of the filter, which I do know at design time.
Here's the definition of the grid:
$(function () { // Define the grid $("#mainGrid_@Model.GridIndex").igGrid({ autoGenerateColumns: false, width: "100%", dataSource: new Array(0), // Just use an empty array to define the dataSource for now. We will populate it with data later dataSourceType: "json", scrolling: true, columns: [ { headerText: "", key: "RowType", dataType: "numeric", hidden: true }, { headerText: "", key: "RowFormat", dataType: "numeric", hidden: true }, { headerText: "", key: "Oversold", width: "25px", dataType: "string" }, { headerText: "", key: "Status", width: "25px", dataType: "string" }, { headerText: "", key: "OrderNumberInfo", width: "100px", dataType: "string" }, { headerText: "", key: "GeneralDescription", width: "200px", dataType: "string" }, { headerText: "", key: "RowDate", width: "150px", dataType: "string" }, { headerText: "", key: "RowDateFormat", dataType: "numeric", hidden: true }, { headerText: "", key: "MultiIndicator", width: "20px", dataType: "string" }, { headerText: "", key: "FobOrTransfer", width: "100px", dataType: "string" }, { headerText: "Pkg", key: "PackageSize", width: "75px", dataType: "string" }, { headerText: "Brd Ft", key: "BoardFeet", width: "90px", dataType: "numeric", format: "###,###,###" } ], features: [ { name: "Filtering", type: "local", mode: "simple", filterSummaryAlwaysVisible: false, renderFilterButton: false, columnSettings: [ { columnKey: "RowFormat", allowFiltering: false }, { columnKey: "Oversold", allowFiltering: false }, { columnKey: "Status", allowFiltering: false }, { columnKey: "OrderNumberInfo", allowFiltering: false }, { columnKey: "GeneralDescription", allowFiltering: false }, { columnKey: "RowDate", allowFiltering: false }, { columnKey: "RowDateFormat", allowFiltering: false }, { columnKey: "MultiIndicator", allowFiltering: false }, { columnKey: "FobOrTransfer", allowFiltering: false }, { columnKey: "PackageSize", allowFiltering: false }, { columnKey: "BoardFeet", allowFiltering: false } ] } ], rowsRendered: function() { FormatGrid('@Model.GridIndex', @Html.Raw(Json.Encode(Model.LengthValues))); } }); // Add the length value columns to the grid. The AddLengthColumns function is in the main page AddLengthColumns('@Model.GridIndex', @Html.Raw(Json.Encode(Model.LengthValues))); // Get the data for the grid. The GetData function is in the main page GetData('@Model.GridIndex', @Html.Raw(Json.Encode(Model))); }); // End onLoad
The functions that add the dynamic columns and perform other duties are here:
function GetData(gridIndex, matrixLayout) { $.ajax({ type: "POST", url: '@Url.Action("GetDataForTable", "Home")', data: matrixLayout, dataType: "json" // we are expecting JSON data back }) .done( function(json) { $("#mainGrid_" + gridIndex).igGrid("option", "dataSource", json); $("#mainGrid_" + gridIndex).igGrid("dataBind"); }) .fail( function(jqXhr, textStatus, errorThrown) { console.warn(jqXhr.responseText); alert(errorThrown + ' getJSON request failed for grid ' + gridIndex, textStatus); }) .always( function() { } ); } function AddLengthColumns(gridIndex, columnList) { // Get var cols = $("#mainGrid_" + gridIndex).igGrid("option", "columns"); // Set - Iterate through the columnList and add new columns for each length value in the list $.each(columnList, function(index, item) { var newColumn = { headerText: item, key: FixLengthHeaderColumnNames(item), width: "75px", dataType: "number", format: "###,###,###" }; cols.push(newColumn); // This is how we signal when a column is oversold var oversoldColumn = { headerText: "", key: "Oversold" + FixLengthHeaderColumnNames(item), width: '0px', dataType: 'bool' } cols.push(oversoldColumn); } ); // Finish $("#mainGrid_" + gridIndex).igGrid("option", "columns", cols); // Now set the filtering for all those new columns to false var colSettings = $("#mainGrid_" + gridIndex).igGridFiltering("option", "columnSettings"); $.each(columnList, function (index, lengthColumnName){ var filterColumn = FixLengthHeaderColumnNames(lengthColumnName); var oversoldFilterColumn = "Oversold" + FixLengthHeaderColumnNames(lengthColumnName); for (var i = 0; i < colSettings.length; i++) { if (colSettings[i].columnKey === filterColumn || colSettings[i].columnKey === oversoldFilterColumn) { colSettings[i].allowFiltering = false; } } }); $("#mainGrid_" + gridIndex).igGridFiltering("option", "columnSettings", colSettings); } function FixLengthHeaderColumnNames(columnName) { return columnName.replace(/[^a-z,A-Z0-9_]/g, '_'); } function FormatGrid(gridIndex, dynamicColumnList) { var gridSelector = "#mainGrid_" + gridIndex; // Contains all the rows for this grid var rows = $(gridSelector).igGrid("rows"); if (rows.length === 0) return; // This happens on the first bind to an empty array, we need to ignore that binding $.each(rows, function(rowIndex, row) { try { var rowBold = $(gridSelector).igGrid("getCellValue", rowIndex, "RowFormat"); if (rowBold !== null && rowBold === 1 || rowBold === '1') { $(row).addClass("rowBoldFormat"); } } catch (e) { console.error("Error trying to bold row " + "Row = " + rowIndex + " " + e); } try { // Date Red/Green formatting var dateFormat = $(gridSelector).igGrid("getCellValue", rowIndex, "RowDateFormat"); if (dateFormat !== null && dateFormat !== undefined) { var dateCellIndex = $(gridSelector).igGrid("getVisibleIndexByKey", "RowDate"); var dateCell = $(gridSelector).igGrid("cellAt", rowIndex, dateCellIndex); if (dateCell !== null && dateCell !== undefined) { if (dateFormat === 1) { $(dateCell).addClass("dateDisplayGreen"); } // 2 is red else if (dateFormat === 2) { $(dateCell).addClass("dateDisplayRed"); } } } } catch (e1) { console.error("Error trying to format Date. " + e1); } $.each(dynamicColumnList, function(columnIndex, dynamicColumn) { try { var oversoldCell = $(gridSelector).igGrid("getCellValue", rowIndex, "Oversold" + dynamicColumn); if (oversoldCell !== null && oversoldCell !== undefined && oversoldCell === true) { var lengthCellIndex = $(gridSelector).igGrid("getVisibleIndexByKey", dynamicColumn); var lengthCell = $(gridSelector).igGrid("cellAt", lengthCellIndex, rowIndex); $(lengthCell).addClass("overSoldHighlight"); var orderCellIndex = $(gridSelector).igGrid("getVisibleIndexByKey", "OrderNumberInfo"); var orderCell = $(gridSelector).igGrid("cellAt", orderCellIndex, rowIndex); $(orderCell).addClass("overSoldHighlight"); var generalDescriptionCellIndex = $(gridSelector).igGrid("getVisibleIndexByKey", "GeneralDescription"); var generalDescriptionCell = $(gridSelector).igGrid("cellAt", generalDescriptionCellIndex, rowIndex); $(generalDescriptionCell).addClass("overSoldHighlight"); var rowDateCellIndex = $(gridSelector).igGrid("getVisibleIndexByKey", "RowDate"); var rowDateCell = $(gridSelector).igGrid("cellAt", rowDateCellIndex, rowIndex); $(rowDateCell).addClass("overSoldHighlight"); var multiIndicatorCellIndex = $(gridSelector).igGrid("getVisibleIndexByKey", "MultiIndicator"); var multiIndicatorCell = $(gridSelector).igGrid("cellAt", multiIndicatorCellIndex, rowIndex); $(multiIndicatorCell).addClass("overSoldHighlight"); } } catch (e2) { console.error("Highlight error for Grid = " + gridSelector + ". Column = Oversold" + dynamicColumn + ". Row = " + rowIndex + ". Error = " + e2); } }); }); } function SwitchView(viewName) { // loop through each of the grid layouts and set the filter to display the proper view var layoutCount = @Model.Layouts.Count; switch (viewName) { case "ForecastByProduct": $("#title").html("Production Forecast Detail"); $("#productionForecastDetailRow").removeClass("displayInline").addClass("displayHidden"); $("#productionForecastSummaryRow").removeClass("displayHidden").addClass("displayInline"); $("#weekOfProductionSummaryRow").removeClass("displayHidden").addClass("displayInline"); $("#vmiProductionDetailRow").removeClass("displayHidden").addClass("displayInline"); break; case "ForecastByProduction": $("#title").html("Production Forecast Summary"); $("#productionForecastDetailRow").removeClass("displayHidden").addClass("displayInline"); $("#productionForecastSummaryRow").removeClass("displayInline").addClass("displayHidden"); $("#weekOfProductionSummaryRow").removeClass("displayHidden").addClass("displayInline"); $("#vmiProductionDetailRow").removeClass("displayHidden").addClass("displayInline"); break; case "ForecastVmi": $("#title").html("VMI Production Forecast Detail"); $("#productionForecastDetailRow").removeClass("displayInline").addClass("displayHidden"); $("#productionForecastSummaryRow").removeClass("displayHidden").addClass("displayInline"); $("#weekOfProductionSummaryRow").removeClass("displayHidden").addClass("displayInline"); $("#vmiProductionDetailRow").removeClass("displayInline").addClass("displayHidden"); break; case "ForecastWeekOf": $("#title").html("Week Of Production Forecast Summary"); $("#productionForecastDetailRow").removeClass("displayInline").addClass("displayHidden"); $("#productionForecastSummaryRow").removeClass("displayHidden").addClass("displayInline"); $("#weekOfProductionSummaryRow").removeClass("displayInline").addClass("displayHidden"); $("#vmiProductionDetailRow").removeClass("displayHidden").addClass("displayInline"); break; } for (var i = 0; i < layoutCount; i++) { SwitchGridView(viewName, i.toString()); } return false; } function SwitchGridView(viewName, gridIndex) { var filters = []; switch(viewName) { case "ForecastByProduct": filters = [ { fieldName: "RowType", expr: 10, cond: "equals", logic: "OR" }, // On Hand Inventory { fieldName: "RowType", expr: 20, cond: "equals", logic: "OR" }, // Order Info { fieldName: "RowType", expr: 30, cond: "equals", logic: "OR" }, // Available to Ship Inventory { fieldName: "RowType", expr: 40, cond: "equals", logic: "OR" }, // Production { fieldName: "RowType", expr: 50, cond: "equals", logic: "OR" }, // Picked / Ready { fieldName: "RowType", expr: 60, cond: "equals", logic: "OR" }, // Picked / Ready Summary { fieldName: "RowType", expr: 70, cond: "equals", logic: "OR" }, // Purchase Order { fieldName: "RowType", expr: 80, cond: "equals", logic: "OR" } // Inbound Transfer ]; break; case "ForecastByProduction": filters = [ { fieldName: "RowType", expr: 10, cond: "equals", logic: "OR" }, // On Hand Inventory //{ fieldName: "RowType", expr: 20, cond: "equals", logic: "OR" }, // Order Info { fieldName: "RowType", expr: 30, cond: "equals", logic: "OR" }, // Available to Ship Inventory { fieldName: "RowType", expr: 40, cond: "equals", logic: "OR" } // Production //{ fieldName: "RowType", expr: 50, cond: "equals", logic: "OR" }, // Picked / Ready //{ fieldName: "RowType", expr: 60, cond: "equals", logic: "OR" }, // Picked / Ready Summary //{ fieldName: "RowType", expr: 70, cond: "equals", logic: "OR" }, // Purchase Order //{ fieldName: "RowType", expr: 80, cond: "equals", logic: "OR" } // Inbound Transfer ]; break; case "ForecastVmi": filters = [ { fieldName: "RowType", expr: 10, cond: "equals", logic: "OR" }, // On Hand Inventory { fieldName: "RowType", expr: 20, cond: "equals", logic: "OR" }, // Order Info { fieldName: "RowType", expr: 30, cond: "equals", logic: "OR" }, // Available to Ship Inventory { fieldName: "RowType", expr: 40, cond: "equals", logic: "OR" } // Production //{ fieldName: "RowType", expr: 50, cond: "equals", logic: "OR" }, // Picked / Ready //{ fieldName: "RowType", expr: 60, cond: "equals", logic: "OR" }, // Picked / Ready Summary //{ fieldName: "RowType", expr: 70, cond: "equals", logic: "OR" }, // Purchase Order //{ fieldName: "RowType", expr: 80, cond: "equals", logic: "OR" } // Inbound Transfer ]; break; case "ForecastWeekOf": filters = [ { fieldName: "RowType", expr: 10, cond: "equals", logic: "OR" }, // On Hand Inventory //{ fieldName: "RowType", expr: 20, cond: "equals", logic: "OR" }, // Order Info { fieldName: "RowType", expr: 30, cond: "equals", logic: "OR" }, // Available to Ship Inventory { fieldName: "RowType", expr: 40, cond: "equals", logic: "OR" } // Production //{ fieldName: "RowType", expr: 50, cond: "equals", logic: "OR" }, // Picked / Ready //{ fieldName: "RowType", expr: 60, cond: "equals", logic: "OR" }, // Picked / Ready Summary //{ fieldName: "RowType", expr: 70, cond: "equals", logic: "OR" }, // Purchase Order //{ fieldName: "RowType", expr: 80, cond: "equals", logic: "OR" } // Inbound Transfer ]; break; } $("mainGrid_" + gridIndex).igGridFiltering("filter", filters); }
The problems I'm running into currently are these.
BTW - I am making the ajax call and getting a JSON return for the data, but the data is not showing up in the grid.
What am I doing wrong?
Oh my goodness. I'm so embarrassed. Thank you.