I've found a bug with the removeData() and removeSelectedData() methods on ListGrid.
I have a ListGrid with a single field (emailField) and a RegExpValidator on that field (basically to ensure that people are entering valid email addresses).
I've also implemented my own Delete button on each row so that I can fire an event when a record is removed; per Svjard's instructions in this thread: http://forums.smartclient.com/showthread.php?t=12594
However, I've found that when a record fails the RegExpValidator (for instance, by entering "foo" as an email address), the RecordClickEvent does not contain a record (i.e. RecordClickEvent.getRecord() returns null - presumably because this is not a valid record.)
As a result, it becomes impossible to call ListGrid.removeData since you don't have a valid record to remove. ListGrid.removeSelectedData throws "com.google.gwt.core.client.JavaScriptException: (String): Invoking an instance method on a null instance" - I suspect because it simply tries to grab the currently selected record and of course that is null as well.
RecordClickEvent.getRecordNum() DOES return a valid index number; but since there is no ListGrid.removeData(int rowNum) method that is no help.
Source code:
The salient part:
I have a ListGrid with a single field (emailField) and a RegExpValidator on that field (basically to ensure that people are entering valid email addresses).
I've also implemented my own Delete button on each row so that I can fire an event when a record is removed; per Svjard's instructions in this thread: http://forums.smartclient.com/showthread.php?t=12594
However, I've found that when a record fails the RegExpValidator (for instance, by entering "foo" as an email address), the RecordClickEvent does not contain a record (i.e. RecordClickEvent.getRecord() returns null - presumably because this is not a valid record.)
As a result, it becomes impossible to call ListGrid.removeData since you don't have a valid record to remove. ListGrid.removeSelectedData throws "com.google.gwt.core.client.JavaScriptException: (String): Invoking an instance method on a null instance" - I suspect because it simply tries to grab the currently selected record and of course that is null as well.
RecordClickEvent.getRecordNum() DOES return a valid index number; but since there is no ListGrid.removeData(int rowNum) method that is no help.
Source code:
Code:
public class EmailListGrid extends ListGrid {
protected ListGridField emailField;
protected ListGridField removeField;
protected Vector<ListGridContentChangedHandler> contentChangeHandlers;
private static final String EMAIL_REG_EXP = "^([a-zA-Z0-9_.\\-+])+@(([a-zA-Z0-9\\-])+\\.)+[a-zA-Z0-9]{2,4}$";
private static final String DEFAULT_VALIDATION_MESSAGE = "Not a valid email address.";
private static final String DEFAULT_SELECTION_EMPTY_MESSAGE = "No Emails";
private static final boolean DEFAULT_SELECTION_CAN_REORDER_MESSAGES = false;
private static final boolean DEFAULT_CAN_DRAG_RECORDS = false;
private static final int DEFAULT_SELECTION_WIDTH=450;
private static final int DEFAULT_SELECTION_HEIGHT=150;
public EmailListGrid(String emailFieldName, String emailFieldLabel)
{
this(emailFieldName,emailFieldLabel,false);
}
public EmailListGrid(String emailFieldName, String emailFieldLabel,boolean canRemoveRecords)
{
super();
contentChangeHandlers = new Vector<ListGridContentChangedHandler>();
this.setShowHeader(false);
this.setWidth(DEFAULT_SELECTION_WIDTH);
this.setHeight(DEFAULT_SELECTION_HEIGHT);
this.setEmptyMessage(DEFAULT_SELECTION_EMPTY_MESSAGE);
this.setCanReorderRecords(DEFAULT_SELECTION_CAN_REORDER_MESSAGES);
this.setCanDragRecordsOut(DEFAULT_CAN_DRAG_RECORDS);
this.setCanAcceptDroppedRecords(DEFAULT_CAN_DRAG_RECORDS);
this.setEditEvent(ListGridEditEvent.DOUBLECLICK);
this.setListEndEditAction(RowEndEditAction.STOP);
emailField = new ListGridField(emailFieldName, emailFieldLabel);
emailField.setCanEdit(true);
RegExpValidator emailValidator = new RegExpValidator();
emailValidator.setExpression(EMAIL_REG_EXP);
emailValidator.setErrorMessage(DEFAULT_VALIDATION_MESSAGE);
emailField.setValidators(emailValidator);
removeField = new ListGridField("remove-field", "",25);
removeField.setAlign(Alignment.CENTER);
removeField.setType(ListGridFieldType.ICON);
removeField.setCellIcon("actions/delete.png");
removeField.setIsRemoveField(true);
removeField.setCanHide(false);
removeField.setCanReorder(false);
removeField.setCanDragResize(false);
removeField.setCanFreeze(false);
removeField.setCanGroupBy(false);
removeField.setCanSort(false);
removeField.setCanEdit(false);
removeField.setShowDefaultContextMenu(false);
this.setFields(emailField,removeField);
emailField.addEditorExitHandler(new EditorExitHandler(){
@Override
public void onEditorExit(EditorExitEvent event) {
notifyListGridContentChangedHandlers(getRecords());
}
});
this.addRecordClickHandler(new RecordClickHandler(){
@Override
public void onRecordClick(RecordClickEvent event) {
if(event.getField().getName().equals("remove-field"))
{
endEditing();
if(event.getRecord()== null)
{
Log.debug("Record was null");
}
removeData(event.getRecord());
}
}
});
}
/**
* @return the emailField
*/
public ListGridField getEmailField() {
return emailField;
}
public String getEmailFieldName() {
return emailField.getName();
}
@Override
public void removeData(Record record)
{
super.removeData(record);
notifyListGridContentChangedHandlers(this.getRecords());
}
public HandlerRegistration addListGridContentChangedHandler(ListGridContentChangedHandler handler)
{
this.contentChangeHandlers.add(handler);
return new ListGridContentChangedHandlerRegistration(handler);
}
public void notifyListGridContentChangedHandlers(ListGridRecord[] listGridRecords)
{
for(ListGridContentChangedHandler handler : contentChangeHandlers)
{
handler.onContentChange(new ListGridContentChangedEvent(listGridRecords));
}
}
private class ListGridContentChangedHandlerRegistration implements HandlerRegistration
{
protected ListGridContentChangedHandler handler;
public ListGridContentChangedHandlerRegistration(ListGridContentChangedHandler handler)
{
this.handler = handler;
}
@Override
public void removeHandler() {
contentChangeHandlers.remove(handler);
}
}
}
The salient part:
Code:
this.addRecordClickHandler(new RecordClickHandler(){
@Override
public void onRecordClick(RecordClickEvent event) {
if(event.getField().getName().equals("remove-field"))
{
endEditing();
if(event.getRecord()== null)
{
Log.debug("Record was null");
}
removeData(event.getRecord());
}
}
});
Comment