Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    Bug: unable to remove record from ListGrid which has validation errors

    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:

    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());
    					
    				}
    				
    			}
    		
    		});

    #2
    Edit: I was able in the end to remove the record in question by doing this:
    Code:
    this.addRecordClickHandler(new RecordClickHandler(){
    
    			@Override
    			public void onRecordClick(RecordClickEvent event) {
    				if(event.getField().getName().equals("remove-field"))
    				{
    				
    					if(event.getRecord()== null)
    					{
    						Log.debug("Record was null");
    						discardEdits(event.getRecordNum(), 0, false);
    					}
    					else
    					{
    						endEditing();
    						removeData(event.getRecord());
    					}
    					
    				}
    				
    			}
    		
    		});
    Not sure if that's the right approach? seems to work ok....

    Comment


      #3
      Is this a non-databound grid? Are you talking about you have a record already added, you try to modify it with an invalid value or this is a brand new record from startEditingNew()?

      Comment


        #4
        Hey Svjard,

        yes, it's a non-databound grid (I'm processing the contents of the grid manually by extracting all the emails and just passing them to the Form as an array).

        And the record is new; i.e. the user clicks a button which calls ListGrid.startEditingNew();

        Comment


          #5
          OK then its not a bug, edits are handled differently, they have to be saved before they are part of the record list. You should be doing it the way you posted in your second post.

          Comment


            #6
            Gotcha, thanks for the response!

            Comment

            Working...
            X