how to do something when a fields value changes in a FORM

hello vaadiners

what kind of listener should I add to a formfield ( a textfield in a form) to save its value to the database when the value changes?

I attach a screenshot to explain the details…

And I also enclose the source code of my form

As you can see it is a kind of master-detail view with a table ( as a master view ), and a form on the bottom left ( as a detail view)

As you can see there is only one editable field on the form ( complexity)

I would like to do the following:

if a change the value/text in the field then do something ( for example save it to the database)

I think I have tried everything to make it happen but nothing happened when I changed the the text in the field

What is wrong with my code and what is the correct way to achieve what I want?

here is my code:


package com.digicpictures.dproject_web.mytickets;

import java.util.HashMap;
import java.util.Iterator;

import com.digicpictures.dproject_web.Dproject_webApplication;
import com.digicpictures.dproject_web.Resource;
import com.digicpictures.dproject_web.Translations;
import com.vaadin.data.Item;
import com.vaadin.ui.ComboBox;
import com.vaadin.ui.Component;
import com.vaadin.ui.DefaultFieldFactory;
import com.vaadin.ui.Field;
import com.vaadin.ui.Form;
import com.vaadin.ui.TextField;

@SuppressWarnings("serial")
public class MyTicketsEditor extends Form    {
	
	Translations translations=null;
	HashMap<String, Resource> resources = null;
	
	private MyTickets master;
	
	final ComboBox issuer=new ComboBox();
    final ComboBox responsible=new ComboBox();
    final ComboBox category=new ComboBox();
    final ComboBox abstractCategory=new ComboBox();
	
	
	
	public MyTicketsEditor (){
		
		setSizeFull();
        setWriteThrough(true); // we want explicit 'apply'
        //setInvalidCommitted(false); // no invalid values in datamodel
        setImmediate(true);
        
        setVisible(true);
        setItemDataSource(null);
       
        
            
        
        
        

    }
	
	/*
     * Override to get control over where fields are placed.
     */
    @Override
    protected void attachField(Object propertyId, Field field) {
       super.attachField(propertyId, field);
    }
	
	
	
	
	
	


	/* (non-Javadoc)
	 * @see com.vaadin.ui.Form#attach()
	 */
	@Override
	public void attach() {
		// TODO Auto-generated method stub
		super.attach();
		
		Dproject_webApplication application =(Dproject_webApplication) getApplication();
		translations=application.translations;
		resources= application.getResourcesMap();
		
		populatePersonComboBoxes();
		
		  setFormFieldFactory(new DefaultFieldFactory() {
	            @Override
	            public Field createField(Item item, Object propertyId,
	                    Component uiContext) {
	                Field field;
	                if (propertyId.equals("dpc_from")) {
	                    field = issuer;
	                }
	                
	                else if (propertyId.equals("dpc_to")) {
	                    field = responsible;
	                }
	                
	                else {
	                    field = super.createField(item, propertyId, uiContext);
	                }
	                
                    
	                field.setReadOnly(true);
	                
	                /* Set null representation of all text fields to empty */
	                if (field instanceof TextField) {
	                    ((TextField) field).setNullRepresentation("");
	                }

	                //field.setWidth("80%");
	                if (propertyId.equals("dpc_name")){
	                	field.setWidth("100%");
	                	
	                }
	                
	                
	                
	                if (propertyId.equals("dpc_complexity")){
	                field.setReadOnly(false);
	                
	                }
	                

	                /* Set the correct caption to each field */
	                for (int i = 0; i < MyTickets.NATURAL_COL_ORDER.length; i++) {
	                    if (MyTickets.NATURAL_COL_ORDER[i]
.equals(propertyId)) {
	                        field.setCaption(master.ColumnHeaders[i]
);
	                    }
	                }
	                return field;
	            }
	        });
		  
		  
	}

	/**
	 * @return the master
	 */
	public MyTickets getMaster() {
		return master;
	}

	/**
	 * @param master the master to set
	 */
	public void setMaster(MyTickets master) {
		this.master = master;
	}
	
	private void  populatePersonComboBoxes () {
    	issuer.addContainerProperty("dpc_name", String.class, "");
    	responsible.addContainerProperty("dpc_name", String.class, "");
    	 	
    	
    	Iterator<Resource> it = resources.values().iterator();
    	while (it.hasNext()) {
    	Resource emp = (Resource) it.next();
    	Item itemIssuer= issuer.addItem(emp.getDpc_handle());
    	Item itemResponsible= responsible.addItem(emp.getDpc_handle());
    	
    	itemIssuer.getItemProperty("dpc_name").setValue(emp.getDpc_name());
    	itemResponsible.getItemProperty("dpc_name").setValue(emp.getDpc_name());
    	
    	}
    	
    	issuer.setItemCaptionPropertyId("dpc_name");
    	responsible.setItemCaptionPropertyId("dpc_name");
    	
    	
    }

	/* (non-Javadoc)
	 * @see com.vaadin.ui.AbstractField#valueChange(com.vaadin.data.Property.ValueChangeEvent)
	 */
	@Override
	public void valueChange(com.vaadin.data.Property.ValueChangeEvent event) {
		// TODO Auto-generated method stub
		super.valueChange(event);
		System.out.println (event.getProperty()+" has been modified");
	}

}

11570.png

Hi Peter,

I’m not entirely convinced that saving to the database when the Complexity field changes is a good idea (from a usability perspective) - but I think you might want to make the field immediate e.g.


if (propertyId.equals("dpc_complexity")){
   field.setReadOnly(false);
   field.setImmediate(true);
}

Cheers,

Charl;es

Thanks for your answer

just a little addition: you have to cast field to texfield to make setImmediate method available

((TextField) field).setImmediate(true);