I have an Ultrawebgrid with a valuelist column (statically loaded with values at Page_Load). When the user selects a value (captured at AfterCellUpdated event), another ValueList is loaded (based on the first valuelist's selected value) and populated for the user to also select.
My problem is that when the grid is loaded, while the second column values are displayed, when clicking on the cells themselves, no valuelist dropdown is shown, because this is not created until the first column dropdownlist is updated.
What I would like to do is to have both value lists loaded and available at page_load, so as to enable editing of the second valuelist without having to change the first column's value first.
Any ideas on how this can be achieved? Which event should I hook this up to?
Hi cloucas,
Can you share your code, used to create the second drop-down? You could try to create both drop downs on page load.
Hi Nikolay
Thanks for your response;
Would you like the code in the code behind or the code in the aspx? They are quite long files, do you want the entire files or the sections relevant to the question?
Just the markup and code-behind for the drop-downs.
OK, then, here goes the aspx first:
var celldescid; function grdTimeSheet_AfterCellUpdateHandler(gridName, cellId) { var totalStaticColumns = 7; // HARDCODED PROVISION var cell1 = igtbl_getCellById(cellId); var cellIndex = cell1.Column.Index; var totalNonChargeableRows = document.getElementById('<%=hdnRowCount.ClientID%>').value; var totalStaticRows = parseFloat(totalNonChargeableRows) + 3; var NonUpdatableRowsFromEnd = 2; var Customer_ID_ColumnIndex = 3; var Customer_name_ColumnIndex = 2; var TypeOfWorkColumnIndex = 5; celldescid = cellId;
if (cellIndex >= totalStaticColumns)// HARDCODED PROVISION {
var grid1 = igtbl_getGridById(gridName); var cell1 = igtbl_getCellById(cellId); var cellIndex = cell1.Column.Index; var RowsCounter = grid1.Rows.length;
//Update the Work Subcategories based on the Work Category selected
if (cellIndex == TypeOfWorkColumnIndex) {
var grid1 = igtbl_getGridById(gridName); var cell1 = igtbl_getCellById(cellId); var selectedValue = cell1.getValue(); PageMethods.Populate_Work_SubType_DropDownList(selectedValue, OnCallWorkSubTypeComplete, OnCallWorkSubTypeTimeOut, OnCallWorkSubTypeError); } }
// Callback function on complete function OnCallWorkSubTypeComplete(result) { var workSubTypeColumnIndex = 6; var ddlArrayContainer; var ddlArrayItem; if (celldescid != null) { //alert('celldescid is not null'); var rowid = window.igtbl_getRowById(celldescid); if (rowid != null) { var cell = rowid.getCell(workSubTypeColumnIndex); if (result.length > 0) { ddlArrayContainer = new Array(result.length); for (var iterator = 0; iterator < result.length; iterator++) { ddlArrayItem = new Array(result[iterator].Name,result[iterator].Name); ddlArrayContainer[iterator] = ddlArrayItem; } cell.Column.ValueList = ddlArrayContainer; //Set by default the selected value to the first value of the array cell.setValue(ddlArrayContainer[0]); } else { cell.setValue(''); cell.Column.ValueList = null; } } } }
function OnCallWorkSubTypeTimeOut(arg) { alert("TimeOut encountered when loading Description" & arg.toString()); }
function OnCallWorkSubTypeError(arg) { alert("Error encountered when loading Description"); }
function BeforeEnterEditMode(tableName, cellName) { celldescid = cellName; var cellColumn = window.igtbl_getColumnById(cellName); if (cellColumn.Key != "Description") return;
var rowId = window.igtbl_getRowById(cellName); var typeOfWorkCell = rowId.getCell(5); var selectedTypeOfWork = typeOfWorkCell.getValue(); window.PageMethods.Populate_Work_SubType_DropDownList(selectedTypeOfWork, OnCallWorkSubTypeComplete, OnCallWorkSubTypeTimeOut, OnCallWorkSubTypeError); }
Now with the code behind file, first the declaration of the categories dropdown, followed by the web method to fetch the subcategories:
Page_Load:
{
Populate_TypeOfWork_GridDropDown();
PopulateWorkDescriptionGridDropDown();
}
private void Populate_TypeOfWork_GridDropDown() { try { DataTable workTypesTable = new DataTable(); workTypesTable.Columns.Add("Work_Id"); workTypesTable.Columns.Add("Work_Description");
List<ASPNET.StarterKit.BusinessLogicLayer.Task> WorkTypesList = ASPNET.StarterKit.BusinessLogicLayer.Task.GetAllTasks(); //CH: The following can also be implemented as a foreach loop... for (int i = 0; i < WorkTypesList.Count; i++) { ASPNET.StarterKit.BusinessLogicLayer.Task workType = WorkTypesList[i]; bool isChargeableTask = workType.Charge; if (isChargeableTask) { DataRow row = workTypesTable.NewRow(); row["Work_Id"] = workType.TaskID; row["Work_Description"] = workType.Description; workTypesTable.Rows.Add(row); } }
ValueList workTypes = grdTimeSheet.DisplayLayout.Bands[0].Columns[TypeOfWorkColumnIndex].ValueList; workTypes.DataSource = workTypesTable; workTypes.ValueMember = "Work_Id"; workTypes.DisplayMember = "Work_Description"; workTypes.DataBind(); grdTimeSheet.DisplayLayout.Bands[0].Columns[TypeOfWorkColumnIndex].Type = ColumnType.DropDownList; grdTimeSheet.DisplayLayout.Bands[0].Columns[TypeOfWorkColumnIndex].ValueList = workTypes; } catch (Exception ex) { Log.updateLog("Error####:" + ex.ToString()); } }
[System.Web.Services.WebMethod] public static List<WorkSubTask> Populate_Work_SubType_DropDownList(int taskId) { var listwst = new List<WorkSubTask>(); try { var subTaskList = SubTask.GetSubTasks(taskId); for (var i = 0; i < subTaskList.Count; i++) { var subtask = subTaskList[i]; var objwst = new WorkSubTask(subtask.Id, subtask.Description); listwst.Add(objwst); } return (listwst); } catch (Exception ex) { Log.updateLog("Error####:" + ex); return null; } }
private void PopulateWorkDescriptionGridDropDown() { var workDescriptionsTable=new DataTable(); workDescriptionsTable.Columns.Add(new DataColumn("Id", typeof (string))); workDescriptionsTable.Columns.Add(new DataColumn("Description", typeof(string))); //Populate the subtasks tabe var workDescriptionsList = SubTask.GetAllSubTasks(); foreach (var subTask in workDescriptionsList) { var newRow = workDescriptionsTable.NewRow(); newRow["Id"] = subTask.Id; newRow["Description"] = subTask.Description; workDescriptionsTable.Rows.Add(newRow); } var workDescriptions = grdTimeSheet.DisplayLayout.Bands[0].Columns[SubTypeOfWorkIndex].ValueList; workDescriptions.ValueMember = "Id"; workDescriptions.DisplayMember = "Description"; workDescriptions.DataBind(); grdTimeSheet.DisplayLayout.Bands[0].Columns[SubTypeOfWorkIndex].Type = ColumnType.DropDownList; grdTimeSheet.DisplayLayout.Bands[0].Columns[SubTypeOfWorkIndex].ValueList = workDescriptions; }
As you can see from the above the following things should be happening:
1. On Page_Load, both value lists (the category and subcategory) are populated.
2. Whenever in the page we have an update of the category field, the subcategory valuelist dropdown is created and populated (by calling the web method above) and its value is set to the first item of the list. (This is wrong, we would prefer have it assume the already selected item).
3. In the BeforeEnterEditMode event, we try to again create and populate the valuelist for the subcategory based on the selected value in the category valuelist.
When executed, and the grid is loaded, the first time we click on the subcategory value list, expecting to get a dropdown, we get no drop-down; only the selected value is highlighted instead. By moving to another cell and then returning back to the sub-category we have the dropdown appear and getting the first value in the list. (we would prefer having selected the value already selected).
I hope all these help you and don't confuse you too much.
Thank you for the provided code. I reviewed it and it seems to be correct. I’m not able to tell why the second dropdown list is empty the first time you open it. I tested the scenario and it was populated during the page load event. If possible, please attach a small running sample, in order to be able to investigate this issue.
By default the dropdown list in UltraWebGrid gets the first value from the list and sets it as a current value when entered edit mode. To prevent this, you could handle the AfterEnterEditMode event like this:
function onAfterEnterEditMode(gridName, cellId, value) {
var val = igtbl_getCellById(cellId).getValue();
igtbl_getCellById(cellId).getElement().getElementsByTagName("select")[0].value = val;
Let me know if you have any further questions.
I will close this question; thank you very much for your help.
I'm following up to see if you have been able to resolve your issue.
Hello,
I could not understand what is exactly the issue. Could you please clarify, and explain the steps to reproduce this behavior? Thank you.
Nikolay Hi
Thanks for your input. At this time I have no other questions on this matter; another issue I am facing is that I have a number of users complaining that whenever the grid is loaded with more and more rows, the time to refresh the totals while jumping from one cell to the other in entering data increases. They claim that after 30 or so rows, they notice a large delay (more than a few seconds). Do you know if there are any limitations?
Hello cloucas,
I'm just checking if you have any other questions.