Possible Solution: Grid with combo editable cell as in attached example
I was looking for a method to edit columns with combo elements.
I finally "emulated" one as shown below.
It works fine on FF (1.5) and on IE 6, IE 7 (had multiple IEs installed) acceptable.
I need comments on this post in order to see what can be improved.
I finally "emulated" one as shown below.
It works fine on FF (1.5) and on IE 6, IE 7 (had multiple IEs installed) acceptable.
I need comments on this post in order to see what can be improved.
var myData = [
["The Godfather", 1, 1, 1972, "USA"],
["Pulp Fiction", 2, 2, 1994, "USA"],
["American Beauty", 3, 3, 1997, "USA"],
["Vertigo", 4, 4, 1958, "USA"],
["Apocalypse Now", 1, 5, 1979, "USA"] // no comma on the last line!
];
var myHeaders = ["Title", "Director", "Genre", "Year", "Country"];
<!-- create controls -->
var itemText1 = ["Francis Ford Coppola","Quentin Tarantino","Sam Mendes","Alfred Hitchcock"];
var itemValues1 = [1,2,3,4];
var itemText2 = ["Crime/Drama","Action/Crime/Drama","Drama","Mystery/Thriller/Romance","Adventure/Drama/War"];
var itemValues2 = [1,2,3,4,5];
var myFooters1 = ["", "", "", ""];
var myFooters2 = ["", "", "", ""];
var list1 = new AW.UI.List;
list1.setItemText(itemText1);
list1.setItemValue(itemValues1);
list1.setItemCount(itemText1.length);
var list2 = new AW.UI.List;
list2.setItemText(itemText2);
list2.setItemValue(itemValues2);
list2.setItemCount(itemText2.length);
var obj = new AW.Grid.Extended;
obj.setCellData(myData);
obj.setCellText(function(c,r){if (c==1) return itemText1[r];if (c==2) return itemText2[r];return myData[r][c]});
obj.setHeaderText(myHeaders);
obj.setColumnCount(4);
obj.setRowCount(5);
obj.setFooterCount(2);
obj.setFooterVisible(true);
//I define a "track" of the cellTemplate
obj.oldTemplate = [null,null,null,null];
//I define an array that holds the current cell being edited as "combo"
obj.currentCellEdited = [null,null];
obj.setCellEditable(true);
//I intend to edit cols 1,2 as combos - I disable cell Edit
obj.setCellEditable(false,1);
obj.setCellEditable(false,2);
/*
Next I define the handlers that would allow me to add combo-edit functionality ...
*/
obj.onCellEditStarted = cellEditStarted;
obj.onCellClicked = cellClicked;
obj.onCellDoubleClicked = cellDblClicked;
obj.onKeyPress = gridKeyPress;
obj.onKeyF2 = gridKeyF2;
obj.onKeyTab = gridKeyTab;
obj.onKeyEnter = gridKeyEnter;
/*
when tapping Tab on cell it should "exit" edit mode for combo object
*/
function gridKeyTab(event)
{
var c = this.currentCellEdited[0];
var r = this.currentCellEdited[1];
var column = this.getCurrentColumn();
var row = this.getCurrentRow();
// try "exiting" edit mode
if (column == c && row == r)
{
this.getCellTemplate(c, r).hidePopup();
this.setCellTemplate(this.oldTemplate[c],c,r);
this.getCellTemplate(c,r).refresh();
this.currentCellEdited = [null, null];
}
}
/*
when tapping Enter on cell it should "enter" or "exit" edit mode for combo object
*/
function gridKeyEnter(event)
{
var c = this.currentCellEdited[0];
var r = this.currentCellEdited[1];
var column = this.getCurrentColumn();
var row = this.getCurrentRow();
// try "exiting" edit mode
if (column == c && row == r)
{
this.getCellTemplate(c, r).hidePopup();
this.setCellTemplate(this.oldTemplate[c],c,r);
this.getCellTemplate(c,r).refresh();
this.currentCellEdited = [null, null];
}
// try "entering" edit mode
if (c === null && r === null)
{
this.onCellEditStarted(this.getCellText(column, row), column, row);
}
}
/*
when tapping any "alphanumeric" key on cell it should "enter" edit mode for combo object
(like editing normal cell)
*/
function gridKeyPress(event)
{
var c = this.currentCellEdited[0];
var r = this.currentCellEdited[1];
var column = this.getCurrentColumn();
var row = this.getCurrentRow();
// try "entering" edit mode
if (c === null && r === null)
{
this.onCellEditStarted(this.getCellText(column, row), column, row);
}
}
/*
when tapping F2 key on cell it should "enter" edit mode for combo object
(like editing normal cell)
*/
function gridKeyF2(event)
{
var c = this.currentCellEdited[0];
var r = this.currentCellEdited[1];
var column = this.getCurrentColumn();
var row = this.getCurrentRow();
// try "entering" edit mode
if (c === null && r === null)
{
this.onCellEditStarted(this.getCellText(column, row), column, row);
}
}
/* When Double-clicking on cell it should "enter" edit mode for combo object
*/
function cellDblClicked(event, column, row)
{
// force "editing" for combo - does nothing for cell template since the called method
// only handles the combo editable columns
this.onCellEditStarted(this.getCellText(column, row), column, row);
}
/*
When clicking on a cell that is not the current cell edited - exit from editing mode
I do not require to validate the combo value since I have the values defined for the
whole column ...
*/
function cellClicked(event, column, row)
{
var c = this.currentCellEdited[0];
var r = this.currentCellEdited[1];
// check if we have a cell currently being edited
if (c !== null && r !== null)
{
if (!(row == r && column == c)) // if we click on a cell that is not the edited cell ...
{
this.getCellTemplate(c, r).hidePopup();
this.setCellTemplate(this.oldTemplate[c],c,r);
this.getCellTemplate(c,r).refresh();
this.currentCellEdited = [null, null];
}
}
//now we are displaying text and value for clicked cell in order to see the changes in grid
this.setFooterText(this.getCellText(column,row), column, 1);
this.getFooterTemplate(column, 1).refresh();
this.setFooterText(this.getCellValue(column,row), column, 0);
this.getFooterTemplate(column, 0).refresh();
}
function cellEditStarted(text, column, row)
{
// if combo editing .... col = 1 or 2
if (column == 2 || column == 1)
{
this.oldTemplate[column] = this.getCellTemplate(column,row)
this.setCellTemplate(new AW.Templates.Combo, column,row);
this.getCellTemplate(column,row).refresh();
this.currentCellEdited = [column,row];
}
}
obj.setPopupTemplate(list1, 1);
obj.setPopupTemplate(list2, 2);
/* add lists onItemClicked handler AFTER SETTING the Popup Template (Alex dixit)
modify the default handler set by sepPopupTemplate to suit my needs
if you want to know the code existing for the handler
execute document.write(list1.onItemClicked); or alert(list1.onItemClicked);
*/
list1.onItemClicked = list2.onItemClicked = function(event,i){
try{
var s=this.getItemText(i);
//get the combo "selectedItem" value
var v=this.getItemValue(i);
this.$owner.setCellText(s,this.$0,this.$1);
// set the value
this.$owner.setCellValue(v,this.$0,this.$1);
AW.$popup.hidePopup();
var e=this.$owner.getCellTemplate(this.$0,this.$1).getContent("box/text").element();
if(AW.ie){e.innerHTML=s}else{e.value=s}
// Fix Firefox "possible" bug - not focusing on cell to allow keys control
e.parentNode.parentNode.focus();
e=null;
}catch(e){}
}
document.write(obj);
Bogdan P.
April 2,