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?
Nikolay thank you for your response and continuing support on this.
I have tried to use the code you submitted; in doing so, I inserted a tag value for the subcategory valuelist in the code-behind as follows:
grdTimeSheet.DisplayLayout.Bands[0].Columns[SubTypeOfWorkIndex].Tag = "Subcategory";
which is executed on Page_Load.
After the grid is populated, as soon as I double-click on the valuelist (subcategory), the program stops at the line:
igtbl_getCellById(cellId).getElement().getElementsByTagName("select")[0].value = val;
Debugging this I can see that at that point the value of igtbl_getCellById(cellId).getElement().getElementsByTagName("Subcategory")[0] is null.
It seems to me that the valuelist is not created at all. I think this is why there is no dropdown at first.
I will try to construct an example of a code and upload it, as the actual page is some 2,500 lines of code (code-behind) and 2,400 lines of aspx. I don't think you would be interested in going through that!
Hi cloucas,
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();
}
Let me know if you have any further questions.
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.
Just the markup and code-behind for the drop-downs.
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?