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