Announcement

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

    "this.form is null or not an object with ValuesManager"

    We have created a custom control that extends TextItem to find a file on the Server. This control works perfectly when it is embedded in a DynamicForm (both in smartGWTPro 2.5 and smartGWTPower 3.0)

    This control also worked perfectly with smartGWTPro 2.5 when used with a ValuesManager linking two dynamic forms on separate tabs. We started having problems when we upgraded to smartGWTPower 3.0 when the control is used with a ValuesManager linking two dynamic forms.



    Code Below for the Tabbed GUI:

    Code:
    public class DataSourceDMI implements EntryPoint {
    	private DataSource dataImportElementDataSource;
    	/** smartGWT ValuesManager used to coordinate between multiple forms linked to the same DataImportElementDS datasource. */
    	private ValuesManager dataImportElementValueManager;
    
        /**
         * This is the entry point method.
         */
        public void onModuleLoad() {
           
        	Log.info("In module load");
        	
        	if (!GWT.isScript()) {
    			KeyIdentifier debugKey = new KeyIdentifier();
    			debugKey.setCtrlKey(true);
    			debugKey.setKeyName("m");
    			Page.registerKey(debugKey, new KeyCallback() {
    				public void execute(String keyName) {
    					SC.showConsole();
    				}
    			});
    		}
    
    		
    		
            VStack vStack = new VStack();
            vStack.setLeft(175);
            vStack.setTop(75);
            vStack.setWidth("70%");
            vStack.setMembersMargin(20);
            
    		Label topLabel = new Label("Test");
    		vStack.addMember(topLabel);
    
    		
    		 
            dataImportElementDataSource = DataSource.get("DataImportElementDS");
    		Log.info("Got DataImportElements datasource " + dataImportElementDataSource);
    		dataImportElementValueManager = new ValuesManager(); // used to combine form data management across tabs
    		dataImportElementValueManager.setDataSource(dataImportElementDataSource);
            
    		
    		TabSet tabSet = new TabSet();
    		tabSet.setSize("100%", "*");
    
    		//  first tab
    		Tab tab1 = new Tab("Tab1");
    		DynamicForm form1 = setupForm1();
    		tab1.setPane(form1);
    		tabSet.addTab(tab1);
    
    		//second tab
    		Tab tab2 = new Tab("tab2");
    		DynamicForm form2 = setupForm2();	
    		tab2.setPane(form2);
    		tabSet.addTab(tab2);
         
            vStack.addMember(tabSet);
    		
            
    		
            vStack.draw();
        }
        
        /**  Create the form for tab1  */
        private DynamicForm setupForm1(){
        	 Log.info("Creating form");
             DynamicForm form = new DynamicForm();
             form.setValuesManager(dataImportElementValueManager);
             form.setNumCols(2);
             form.setColWidths(110, "*");
             form.setPadding(5);
             form.setSize("550", "70");
     		
             Log.info("Adding picker");
             
             /** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
             
             final TextItem picker = new ServerSideExcelFilePicker("excelFileName", "Excel File Name");
     		
             //  if replace line above with the following, no problem encountered
             //final TextItem picker = new TextItem("excelFileName", "Excel File Name");
             
             /***  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
             
             
             picker.setWidth("*");		
     		form.setFields(picker);
     		return form;
        }
        
        /**  Create the form for tab1  */
        private DynamicForm setupForm2(){
        	 Log.info("Creating form");
             DynamicForm form = new DynamicForm();
             form.setValuesManager(dataImportElementValueManager);
             form.setNumCols(2);
             form.setColWidths(110, "*");
             form.setPadding(5);
             form.setSize("550", "70");
     		
             Log.info("Adding picker");
             final TextItem item = new TextItem("worksheet", "Excel Worksheet");
     		item.setWidth("*");		
     		form.setFields(item);
     		return form;
        }   
    }
    Code below for the custom control:

    Code:
    public class ServerSideExcelFilePicker extends ServerSideFilePicker {
    
    	public ServerSideExcelFilePicker(String name, String title) {		
    		super(name, title);
    		Log.info("Constructing Excel file picker.");
    		this.setFileFilter(".*?xls");
    	}	
    }
    
    public class ServerSideFilePicker extends TextItem {
    
    	private static Dialog dialog;
    	private static ServerSideFilePicker currentEditor;
    
    	/**
    	 * An optional filter used to limit the files displayed by this file picker. For example, can set to ".xls" to limit returned files to excel files. If is
    	 * null, no filtering done.
    	 */
    	private String fileFilter = null;
    
    	/**
    	 * Constructor
    	 * 
    	 * @param name name of this file picker form item
    	 * @param title String title to associate with this file picker
    	 * @param callingForm the calling form. Required for work-around to trigger change events on calling form when picker value is set programatically.
    	 */
    	public ServerSideFilePicker(String name, String title) {
    		super(name, title);
    		Log.info("Constructing file picker");
    		this.setWidth(400);
    		PickerIcon searchPicker = new PickerIcon(PickerIcon.SEARCH);
    		setIcons(searchPicker);
    		addIconClickHandler(new IconClickHandler() {
    			public void onIconClick(IconClickEvent event) {
    
    				Log.info("Responding to click on file picker icon");
    				// get global coordinates of the clicked picker icon
    				Rectangle iconRect = getIconPageRect(event.getIcon());
    
    				// remember what editor is active, so we can set its value from the picker dialog
    				ServerSideFilePicker.currentEditor = ServerSideFilePicker.this;
    
    				// get the current value of the text item. Send to the dialog as the current file to display
    				String directory = ServerSideFilePicker.currentEditor.getValueAsString();
    
    				// lazily create the the server side directory display dialog when the picker is first used
    				if (ServerSideFilePicker.dialog == null) {
    					Log.info("Dialog is null, creating new dialog.");
    					dialog = new ServerSideFileDisplayDialog(directory, fileFilter);
    				} else {
    					// TODO send new criteria to dialog to change files displayed
    				}
    
    				// show the picker dialog
    				Log.info("About to show dialog");
    				ServerSideFilePicker.showDialog(iconRect.getLeft(), iconRect.getTop());
    			}
    		});
    	}
    
    	public String getFileFilter() {
    		return fileFilter;
    	}
    
    	/**
    	 * A regular expression used to filter the files returned by this user interface.
    	 * 
    	 * @param fileFilter
    	 */
    	public void setFileFilter(String fileFilter) {
    		this.fileFilter = fileFilter;
    	}
    
    	// set the specified value and dismiss the picker dialog
    	protected static void setCurrentValue(String value) {
    		String oldVal = currentEditor.getValueAsString();
    		currentEditor.setValue(value);
    		dialog.hide();
    
    	}
    
    	/**  Work around to force setValue to fire a change event.  
    	 * 
    	 */
    	private native void fireChangedEvent() /*-{
    		var obj = null;
    		obj = this.@com.smartgwt.client.core.DataClass::getJsObj()();
    		var selfJ = this;
    		if (obj.getValue === undefined) {
    			return;
    		}
    		var param = {
    			"form" : obj.form,
    			"item" : obj,
    			"value" : obj.getValue()
    		};
    		var event = @com.smartgwt.client.widgets.form.fields.events.ChangedEvent::new(Lcom/google/gwt/core/client/JavaScriptObject;)(param);
    		selfJ.@com.smartgwt.client.core.DataClass::fireEvent(Lcom/google/gwt/event/shared/GwtEvent;)(event);
    	}-*/;
    
    	@Override
    	public void setValue(String value) {
    		super.setValue(value);
    		Log.info("In overidden setValue method.  Firing changge event");
    		fireChangedEvent();
    	}
    
    	// show the picker dialog at the specified position
    	protected static void showDialog(int left, int top) {
    		dialog.show();
    		dialog.moveTo(left, top);
    	}
    
    	protected static void hideDialog() {
    		dialog.hide();
    	}
    We receive the following stack trace on module load:

    18:07:10.688:INFO:Log:initialized
    18:07:10.691:WARN:Page:NOTE: isc.Page.getWidth() called before <BODY> tag was written out -- value cannot be determined. Returning 500
    18:07:10.691:WARN:Page:NOTE: isc.Page.getHeight() called before <BODY> tag was written out -- value cannot be determined. Returning 500
    18:07:10.968:WARN:Log:New Class ID: 'EditPane' collides with ID of existing Class object '[DataSource ID:EditPane]'. Existing object will be replaced.
    This conflict would be avoided by disabling ISC Simple Names mode. See documentation for further information.
    18:07:11.020:INFO:Log:isc.Page is loaded
    18:07:37.339:WARN:DynamicForm:isc_DynamicForm_0:destroyed FormItem passed to setItems()/addItem(): FormItems cannot be re-used with different DynamicForms
    18:07:37.386:WARN:Log:Error:
    ''this.form' is null or not an object'
    in http://127.0.0.1:8888/dsdmi/sc/modules/ISC_Forms.js
    at line 1572
    FormItem.isDisabled()
    FormItem.iconIsDisabled(_1=>Obj{name:_0}, _2=>undef)
    FormItem.$36c(_1=>Obj{name:_0})
    FormItem.$14v()
    FormItem.init([TextItem ID:isc_TextItem_0 name:excelFileName], undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef)
    Class.invokeSuper(_1=>null, _2=>"init", _3=>undef, _4=>undef, _5=>undef, _6=>undef, _7=>undef, _8=>undef, _9=>undef, _10=>undef)
    Class.Super(_1=>"init", _2=>Obj{length:13}, _3=>undef)
    TextItem.init([TextItem ID:isc_TextItem_0 name:excelFileName], undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef, undef)
    Class.completeCreation(_1=>[TextItem ID:isc_TextItem_0 name:excelFileName], _2=>undef, _3=>undef, _4=>undef, _5=>undef, _6=>undef, _7=>undef, _8=>undef, _9=>undef, _10=>undef, _11=>undef, _12=>undef, _13=>undef)
    DynamicForm.createItem(_1=>[TextItem ID:isc_TextItem_0 name:excelFileName], _2=>"TextItem")
    DynamicForm.$10l(_1=>Array[1], _2=>null, _3=>true, _4=>undef)
    DynamicForm.setItems(_1=>Array[1], _2=>undef)
    DynamicForm.setFields(_1=>Array[0])
    Canvas.setDataSource(_1=>[DataSource ID:DataImportElementDS], _2=>Array[0])
    ** recursed on Class.invokeSuper

    Would very much appreciate support on this problem.

    I have a very basic Eclipse project (4 client-side and 4 server-side classes) that re-produces the problem based on DataSourceDMI in the samples that I can forward if that is helpful.

    #2
    Can you let us know if you're reproducing this with the fully patched version (see smartclient.com/builds)?

    Comment


      #3
      I just downloaded the 1/27 build. I am getting the same errors. Let me know if you want the small Eclipse project that reproduces the problem. I would be pleased to forward it to you.

      Comment


        #4
        We would definitely appreciate a way to reproduce the problem, but the ideal format is just code we can paste into onModuleLoad() from a standard project. This avoids us having to troubleshoot/fix anything in your project that may be expecting .jars in certain locations, etc.

        Comment


          #5
          Okay, I've got it simplified down to just the client side code:

          Module Load class:

          Code:
          package com.smartgwt.sample.client;
          
          
          import com.google.gwt.core.client.EntryPoint;
          import com.google.gwt.core.client.GWT;
          import com.smartgwt.client.core.KeyIdentifier;
          import com.smartgwt.client.data.DataSource;
          import com.smartgwt.client.util.KeyCallback;
          import com.smartgwt.client.util.Page;
          import com.smartgwt.client.util.SC;
          import com.smartgwt.client.widgets.Label;
          import com.smartgwt.client.widgets.form.DynamicForm;
          import com.smartgwt.client.widgets.form.ValuesManager;
          import com.smartgwt.client.widgets.form.fields.TextItem;
          import com.smartgwt.client.widgets.layout.VStack;
          import com.smartgwt.client.widgets.tab.Tab;
          import com.smartgwt.client.widgets.tab.TabSet;
          
          /**
           * Entry point classes define <code>onModuleLoad()</code>.
           */
          public class DataSourceDMI implements EntryPoint {
          	private DataSource dataImportElementDataSource;
          	/** smartGWT ValuesManager used to coordinate between multiple forms linked to the same DataImportElementDS datasource. */
          	private ValuesManager dataImportElementValueManager;
          
              /**
               * This is the entry point method.
               */
              public void onModuleLoad() {
                 
              	
              	if (!GWT.isScript()) {
          			KeyIdentifier debugKey = new KeyIdentifier();
          			debugKey.setCtrlKey(true);
          			debugKey.setKeyName("m");
          			Page.registerKey(debugKey, new KeyCallback() {
          				public void execute(String keyName) {
          					SC.showConsole();
          				}
          			});
          		}
          
          		
          		
                  VStack vStack = new VStack();
                  vStack.setLeft(175);
                  vStack.setTop(75);
                  vStack.setWidth("70%");
                  vStack.setMembersMargin(20);
                  
          		Label topLabel = new Label("Test");
          		vStack.addMember(topLabel);
          
          		
          		dataImportElementDataSource = new DataSource(); 
                 // dataImportElementDataSource = DataSource.get("DataImportElementDS");
          		dataImportElementValueManager = new ValuesManager(); // used to combine form data management across tabs
          		dataImportElementValueManager.setDataSource(dataImportElementDataSource);
                  
          		
          		TabSet tabSet = new TabSet();
          		tabSet.setSize("100%", "*");
          
          		//  first tab
          		Tab tab1 = new Tab("Tab1");
          		DynamicForm form1 = setupForm1();
          		tab1.setPane(form1);
          		tabSet.addTab(tab1);
          
          		//second tab
          		Tab tab2 = new Tab("tab2");
          		DynamicForm form2 = setupForm2();	
          		tab2.setPane(form2);
          		tabSet.addTab(tab2);
               
                  vStack.addMember(tabSet);
          		
                  
          		
                  vStack.draw();
              }
              
              /**  Create the form for tab1  */
              private DynamicForm setupForm1(){
                   DynamicForm form = new DynamicForm();
                   //form.setID("form1");      DIDN'T FIX BUG
                   form.setValuesManager(dataImportElementValueManager);
                   form.setNumCols(2);
                   form.setColWidths(110, "*");
                   form.setPadding(5);
                   form.setSize("550", "70");
           		
                   
                   /** !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
                   
                   final TextItem picker = new ServerSideFilePicker("excelFileName", "Excel File Name");
           		
                   //  if replace line above with the following, no problem encountered
                   //final TextItem picker = new TextItem("excelFileName", "Excel File Name");
                   
                   /***  !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!*/
                   
                   
                   picker.setWidth("*");		
           		form.setFields(picker);
           		return form;
              }
              
              /**  Create the form for tab1  */
              private DynamicForm setupForm2(){
                   DynamicForm form = new DynamicForm();
                  // form.setID("form2");     DIDN'T HELP BUG
                   form.setValuesManager(dataImportElementValueManager);
                   form.setNumCols(2);
                   form.setColWidths(110, "*");
                   form.setPadding(5);
                   form.setSize("550", "70");
           		
                   final TextItem item = new TextItem("worksheet", "Excel Worksheet");
           		item.setWidth("*");		
           		form.setFields(item);
           		return form;
              }
              
              
              
              
          }

          Class that extends TextItem that causes the crash. If this class is replaced with a generic TextItem, the problem does not occur. See lines of code above marked with "!!!!!!!!!!!!!!!!!!!!!" to see this option.

          Code:
          package com.smartgwt.sample.client;
          
          import com.smartgwt.client.core.Rectangle;
          import com.smartgwt.client.widgets.Dialog;
          import com.smartgwt.client.widgets.form.fields.PickerIcon;
          import com.smartgwt.client.widgets.form.fields.TextItem;
          import com.smartgwt.client.widgets.form.fields.events.IconClickEvent;
          import com.smartgwt.client.widgets.form.fields.events.IconClickHandler;
          import com.allen_sauer.gwt.log.client.Log;
          
          
          public class ServerSideFilePicker extends TextItem {
          
          	private static Dialog dialog;
          	private static ServerSideFilePicker currentEditor;
          
          	/**
          	 * An optional filter used to limit the files displayed by this file picker. For example, can set to ".xls" to limit returned files to excel files. If is
          	 * null, no filtering done.
          	 */
          	private String fileFilter = null;
          
          	/**
          	 * Constructor
          	 * 
          	 * @param name name of this file picker form item
          	 * @param title String title to associate with this file picker
          	 * @param callingForm the calling form. Required for work-around to trigger change events on calling form when picker value is set programatically.
          	 */
          	public ServerSideFilePicker(String name, String title) {
          		super(name, title);
          		Log.info("Constructing file picker");
          		this.setWidth(400);
          		PickerIcon searchPicker = new PickerIcon(PickerIcon.SEARCH);
          		setIcons(searchPicker);
          		addIconClickHandler(new IconClickHandler() {
          			public void onIconClick(IconClickEvent event) {
          
          				Log.info("Responding to click on file picker icon");
          				// get global coordinates of the clicked picker icon
          				Rectangle iconRect = getIconPageRect(event.getIcon());
          
          				// remember what editor is active, so we can set its value from the picker dialog
          				ServerSideFilePicker.currentEditor = ServerSideFilePicker.this;
          
          				// get the current value of the text item. Send to the dialog as the current file to display
          				String directory = ServerSideFilePicker.currentEditor.getValueAsString();
          
          				// lazily create the the server side directory display dialog when the picker is first used
          				if (ServerSideFilePicker.dialog == null) {
          					Log.info("Dialog is null, creating new dialog.");
          					dialog = new ServerSideFileDisplayDialog(directory, fileFilter);
          					dialog.setID("ServerSideFilePickerDialog");
          				} else {
          					// TODO send new criteria to dialog to change files displayed
          				}
          
          				// show the picker dialog
          				Log.info("About to show dialog");
          				ServerSideFilePicker.showDialog(iconRect.getLeft(), iconRect.getTop());
          			}
          		});
          	}
          
          	public String getFileFilter() {
          		return fileFilter;
          	}
          
          	/**
          	 * A regular expression used to filter the files returned by this user interface.
          	 * 
          	 * @param fileFilter
          	 */
          	public void setFileFilter(String fileFilter) {
          		this.fileFilter = fileFilter;
          	}
          
          	// set the specified value and dismiss the picker dialog
          	protected static void setCurrentValue(String value) {
          		String oldVal = currentEditor.getValueAsString();
          		currentEditor.setValue(value);
          		dialog.hide();
          
          	}
          
          	/**  Work around to force setValue to fire a change event.  
          	 * 
          	 */
          	private native void fireChangedEvent() /*-{
          		var obj = null;
          		obj = this.@com.smartgwt.client.core.DataClass::getJsObj()();
          		var selfJ = this;
          		if (obj.getValue === undefined) {
          			return;
          		}
          		var param = {
          			"form" : obj.form,
          			"item" : obj,
          			"value" : obj.getValue()
          		};
          		var event = @com.smartgwt.client.widgets.form.fields.events.ChangedEvent::new(Lcom/google/gwt/core/client/JavaScriptObject;)(param);
          		selfJ.@com.smartgwt.client.core.DataClass::fireEvent(Lcom/google/gwt/event/shared/GwtEvent;)(event);
          	}-*/;
          
          	@Override
          	public void setValue(String value) {
          		super.setValue(value);
          		Log.info("In overidden setValue method.  Firing changge event");
          		fireChangedEvent();
          	}
          
          	// show the picker dialog at the specified position
          	protected static void showDialog(int left, int top) {
          		dialog.show();
          		dialog.moveTo(left, top);
          	}
          
          	protected static void hideDialog() {
          		dialog.hide();
          	}
          
          }
          The final class is the Dialog displayed by the text item when the customized text item icon is clicked:

          Code:
          package com.smartgwt.sample.client;
          
          
          import com.google.gwt.i18n.client.NumberFormat;
          import com.smartgwt.client.data.Criteria;
          import com.smartgwt.client.data.DSCallback;
          import com.smartgwt.client.data.DSRequest;
          import com.smartgwt.client.data.DSResponse;
          import com.smartgwt.client.data.DataSource;
          import com.smartgwt.client.data.Record;
          import com.smartgwt.client.types.Alignment;
          import com.smartgwt.client.types.DateDisplayFormat;
          import com.smartgwt.client.types.ListGridFieldType;
          import com.smartgwt.client.types.VerticalAlignment;
          import com.smartgwt.client.widgets.Button;
          import com.smartgwt.client.widgets.Dialog;
          import com.smartgwt.client.widgets.Label;
          import com.smartgwt.client.widgets.events.ClickEvent;
          import com.smartgwt.client.widgets.events.ClickHandler;
          import com.smartgwt.client.widgets.grid.CellFormatter;
          import com.smartgwt.client.widgets.grid.ListGrid;
          import com.smartgwt.client.widgets.grid.ListGridField;
          import com.smartgwt.client.widgets.grid.ListGridRecord;
          import com.smartgwt.client.widgets.grid.events.RecordDoubleClickEvent;
          import com.smartgwt.client.widgets.grid.events.RecordDoubleClickHandler;
          import com.smartgwt.client.widgets.layout.HLayout;
          import com.smartgwt.client.widgets.layout.HStack;
          import com.smartgwt.client.widgets.layout.LayoutSpacer;
          import com.smartgwt.client.widgets.layout.VLayout;
          
          public class ServerSideFileDisplayDialog extends Dialog {
          	Label lblFoldervalue;
          	String importDirectory = null;
          	DataSource serverSideFileSystemDMI;
          	private final ListGrid serverFilesListGrid;
          	private final String filter;
          	private HLayout folderHLayout;
          	private VLayout vLayout;
          	/**
          	 * Constructor
          	 * 
          	 * @param directory String directory to show files for
          	 * @param filter Regex filter to filter the files displayed
          	 */
          	public ServerSideFileDisplayDialog(String directory, String filt) {
          		super();
          
          		filter = filt;
          		this.setLayoutMargin(5);
          		this.setIsModal(true);
          		this.setShowHeader(true);
          		this.setShowEdges(true);
          		// this.setEdgeSize(10);
          		this.setShowToolbar(false);
          		this.setBackgroundColor("white");
          		this.setTitle("");
          		setSize("600", "400");
          		vLayout = new VLayout();
          		vLayout.setSize("100%", "100%");
          		vLayout.setMembersMargin(5);
          
          		Label lblServersideFolder = new Label("Folder");
          		lblServersideFolder.setSize("600", "20");
          		vLayout.addMember(lblServersideFolder); // index 0
          
          		folderHLayout = new HLayout();
          		folderHLayout.setHeight("30");
          		folderHLayout.setDefaultLayoutAlign(VerticalAlignment.CENTER);
          		folderHLayout.setMembersMargin(5);
          		folderHLayout.setAlign(VerticalAlignment.CENTER);
          
          		lblFoldervalue = new Label(directory);
          		lblFoldervalue.setSize("*", "24");
          		folderHLayout.addMember(lblFoldervalue);
          
          
          		Button btnUpbutton = new Button();   // go up a directory folder in the hierarchy
          		btnUpbutton.setIcon("up16.png");
          		btnUpbutton.setWidth(24);
          		btnUpbutton.setHeight(24);
          		btnUpbutton.setTooltip("Move up a folder");
          		btnUpbutton.addClickHandler(new ClickHandler() {
          			public void onClick(ClickEvent event) {
          				String currentDir = lblFoldervalue.getTitle();						
          				String fullPath = currentDir+"..";
          				fetchServerFileData(fullPath, filter, vLayout, serverFilesListGrid);
          			
          			}
          		});
          
          		folderHLayout.addMember(btnUpbutton);
          		vLayout.addMember(folderHLayout);
          
          		Label filesLabel = new Label("Files");
          		filesLabel.setSize("200", "20");
          		vLayout.addMember(filesLabel);
          
          		serverSideFileSystemDMI = DataSource.get("ServerSideFileSystemDMI");
          		if (serverSideFileSystemDMI == null) {
          			//Log.warn("Couldn't find ServerSideFileSystemDMI datasource.  Is the datasource registered in AtlanticSchedule.html? ");
          			//Log.warn("Or couldn't find ds.xml file.");
          		}
          
          		
          		serverFilesListGrid = new ListGrid();
          		serverFilesListGrid.setSize("100%", "*");
          
          		serverFilesListGrid.setShowHeader(true);
          		serverFilesListGrid.setShowAllRecords(true);
          		serverFilesListGrid.setCanReorderRecords(false);
          		serverFilesListGrid.setCanRemoveRecords(false);
          		serverFilesListGrid.setCanEdit(false);
          		serverFilesListGrid.setCanMultiSort(false);
          		serverFilesListGrid.setUseAllDataSourceFields(true);
          		serverFilesListGrid.setDataSource(serverSideFileSystemDMI);
          		serverFilesListGrid.setDateFormatter(DateDisplayFormat.TOUSSHORTDATETIME);
          		serverFilesListGrid.setDatetimeFormatter(DateDisplayFormat.TOUSSHORTDATETIME);
          		serverFilesListGrid.setSelectionProperty("isSelected");
          		serverFilesListGrid.addRecordDoubleClickHandler(new RecordDoubleClickHandler() {
          
          			@Override
          			public void onRecordDoubleClick(RecordDoubleClickEvent event) {
          				SelectedFileClickHandler handler = new SelectedFileClickHandler();
          				handler.onClick(null);
          			}
          
          		});
          
          		// Want to show icons instead of the words "file" or "directory" in the list grid
          		ListGridField typeField = new ListGridField("type", 40);
          		typeField.setAlign(Alignment.CENTER);
          		typeField.setType(ListGridFieldType.IMAGE);
          		typeField.setImageURLSuffix(".png");
          
          		ListGridField fileSizeField = new ListGridField("fileSize", 60);
          		fileSizeField.setAlign(Alignment.RIGHT);
          		fileSizeField.setCellFormatter(new CellFormatter() {
          			public String format(Object value, ListGridRecord record, int rowNum, int colNum) {
          				NumberFormat nf = NumberFormat.getFormat("#,##0");
          				try {
          					return nf.format(((Number) value).longValue());
          				} catch (Exception e) {
          					return value.toString();
          				}
          			}
          		});
          
          		ListGridField permissionsField = new ListGridField("permissions", 80);
          		permissionsField.setAlign(Alignment.CENTER);
          
          		serverFilesListGrid.setFields(new ListGridField[] { typeField, fileSizeField, permissionsField });
          		// serverFilesListGrid.setUseAllDataSourceFields(true);
          
          		vLayout.addMember(serverFilesListGrid);
          
          		LayoutSpacer spacer = new LayoutSpacer();
          		spacer.setWidth(100);
          		spacer.setHeight(10);
          		vLayout.addMember(spacer);
          
          		HStack buttonHStack = new HStack();
          		buttonHStack.setSize("500", "40");
          		buttonHStack.setMembersMargin(10);
          
          		Button okButton = new Button("Okay");
          		buttonHStack.addMember(okButton);
          		okButton.addClickHandler(new SelectedFileClickHandler());
          
          		Button btnCancel = new Button("Cancel");
          		buttonHStack.addMember(btnCancel);
          		btnCancel.addClickHandler(new ClickHandler() {
          			public void onClick(ClickEvent event) {
          				ServerSideFilePicker.hideDialog();
          			}
          		});
          
          		vLayout.addMember(buttonHStack);
          		addMember(vLayout);
          
          		fetchServerFileData(directory, filter, vLayout, serverFilesListGrid);
          	}
          
          	class SelectedFileClickHandler implements ClickHandler {
          
          		public void onClick(ClickEvent event) {
          			//Log.info("Running onClick method for a selected file event.");
          			ListGridRecord record = serverFilesListGrid.getSelectedRecord();
          			if (record == null) {
          				ServerSideFilePicker.hideDialog();
          			}
          
          			String type = record.getAttributeAsString("type");
          			if (type.equalsIgnoreCase("directory")) {
          				String path = record.getAttributeAsString("path");
          				String filename = record.getAttributeAsString("name");
          				String fullPath = path + filename;
          				fetchServerFileData(fullPath, filter, vLayout, serverFilesListGrid);
          
          			} else {
          				String path = record.getAttributeAsString("path");
          				String filename = record.getAttributeAsString("name");
          				String fullPath = path + filename;
          				ServerSideFilePicker.setCurrentValue(fullPath); // sets the picker value to the selected file and hides this dialog
          				
          			}
          
          		}
          
          	}
          
          	/**
          	 * Fetches data about the files in the specified server directory and returns them to the ListGrid
          	 * 
          	 * @param directory String directory to locate on the server and retrieve file information about
          	 * @param filter Regex filter to filter the returned server files by
          	 * @param vLayout VLayout that contains the folder label that is replaced by this fetch
          	 * @param serverFilesListGrid The listgrid that displays the folders and files in the passed directory
          	 */
          	private void fetchServerFileData(String directory, String filter, final VLayout vLayout, final ListGrid serverFilesListGrid) {
          		Criteria folderCriteria = new Criteria();
          
          		if (directory != null && directory.trim().length() > 0) {
          			folderCriteria.addCriteria("directory", directory);
          		}
          
          		if (filter != null && filter.trim().length() > 0) {
          			folderCriteria.addCriteria("filter", filter);
          		}
          
          		serverFilesListGrid.fetchData(folderCriteria, new DSCallback() {
          
          			/**
          			 * Get the parent folder the file list is displaying by grabbing the hidden property,"path", from the first file record displayed. Replace the
          			 * folder value label with the parent folder name.
          			 */
          			public void execute(DSResponse response, Object rawData, DSRequest request) {
          
          				//Log.info("Fetched the files from the server.  ");
          				if (response.getStatus() == DSResponse.STATUS_SUCCESS && response.getTotalRows() >= 1) {
          
          					Record[] records = response.getData();
          					Record returnRecord = records[0];
          					String folder = returnRecord.getAttribute("path");
          					if (folder != null && folder.trim().length() != 0) {
          						folderHLayout.removeMember(lblFoldervalue);
          						lblFoldervalue = new Label(folder);
          						lblFoldervalue.setSize("600", "20");
          						folderHLayout.addMember(lblFoldervalue, 2);
          					}
          				}
          			}
          		});
          	}
          
          }
          I believe the above classes should be sufficient to reproduce the module load error. Please let me know if you need anything else.

          Comment


            #6
            I accidentally kept some Log statements that might cause you problems in the second class I posted earlier if you don't have the logging library. Here it is again without the Log statements:

            Code:
            package com.smartgwt.sample.client;
            
            import com.smartgwt.client.core.Rectangle;
            import com.smartgwt.client.widgets.Dialog;
            import com.smartgwt.client.widgets.form.fields.PickerIcon;
            import com.smartgwt.client.widgets.form.fields.TextItem;
            import com.smartgwt.client.widgets.form.fields.events.IconClickEvent;
            import com.smartgwt.client.widgets.form.fields.events.IconClickHandler;
            
            
            public class ServerSideFilePicker extends TextItem {
            
            	private static Dialog dialog;
            	private static ServerSideFilePicker currentEditor;
            
            	/**
            	 * An optional filter used to limit the files displayed by this file picker. For example, can set to ".xls" to limit returned files to excel files. If is
            	 * null, no filtering done.
            	 */
            	private String fileFilter = null;
            
            	/**
            	 * Constructor
            	 * 
            	 * @param name name of this file picker form item
            	 * @param title String title to associate with this file picker
            	 * @param callingForm the calling form. Required for work-around to trigger change events on calling form when picker value is set programatically.
            	 */
            	public ServerSideFilePicker(String name, String title) {
            		super(name, title);
            		this.setWidth(400);
            		PickerIcon searchPicker = new PickerIcon(PickerIcon.SEARCH);
            		setIcons(searchPicker);
            		addIconClickHandler(new IconClickHandler() {
            			public void onIconClick(IconClickEvent event) {
            
            				// get global coordinates of the clicked picker icon
            				Rectangle iconRect = getIconPageRect(event.getIcon());
            
            				// remember what editor is active, so we can set its value from the picker dialog
            				ServerSideFilePicker.currentEditor = ServerSideFilePicker.this;
            
            				// get the current value of the text item. Send to the dialog as the current file to display
            				String directory = ServerSideFilePicker.currentEditor.getValueAsString();
            
            				// lazily create the the server side directory display dialog when the picker is first used
            				if (ServerSideFilePicker.dialog == null) {
            					dialog = new ServerSideFileDisplayDialog(directory, fileFilter);
            					dialog.setID("ServerSideFilePickerDialog");
            				} else {
            					// TODO send new criteria to dialog to change files displayed
            				}
            
            				// show the picker dialog
            				ServerSideFilePicker.showDialog(iconRect.getLeft(), iconRect.getTop());
            			}
            		});
            	}
            
            	public String getFileFilter() {
            		return fileFilter;
            	}
            
            	/**
            	 * A regular expression used to filter the files returned by this user interface.
            	 * 
            	 * @param fileFilter
            	 */
            	public void setFileFilter(String fileFilter) {
            		this.fileFilter = fileFilter;
            	}
            
            	// set the specified value and dismiss the picker dialog
            	protected static void setCurrentValue(String value) {
            		String oldVal = currentEditor.getValueAsString();
            		currentEditor.setValue(value);
            		dialog.hide();
            
            	}
            
            	/**  Work around to force setValue to fire a change event.  
            	 * 
            	 */
            	private native void fireChangedEvent() /*-{
            		var obj = null;
            		obj = this.@com.smartgwt.client.core.DataClass::getJsObj()();
            		var selfJ = this;
            		if (obj.getValue === undefined) {
            			return;
            		}
            		var param = {
            			"form" : obj.form,
            			"item" : obj,
            			"value" : obj.getValue()
            		};
            		var event = @com.smartgwt.client.widgets.form.fields.events.ChangedEvent::new(Lcom/google/gwt/core/client/JavaScriptObject;)(param);
            		selfJ.@com.smartgwt.client.core.DataClass::fireEvent(Lcom/google/gwt/event/shared/GwtEvent;)(event);
            	}-*/;
            
            	@Override
            	public void setValue(String value) {
            		super.setValue(value);
            		fireChangedEvent();
            	}
            
            	// show the picker dialog at the specified position
            	protected static void showDialog(int left, int top) {
            		dialog.show();
            		dialog.moveTo(left, top);
            	}
            
            	protected static void hideDialog() {
            		dialog.hide();
            	}
            
            }

            Comment


              #7
              Uhh.. try it without your JSNI hack to force firing a change event :)

              Comment


                #8
                Class without extra code below:

                Code:
                package com.smartgwt.sample.client;
                
                import com.smartgwt.client.core.Rectangle;
                import com.smartgwt.client.widgets.Dialog;
                import com.smartgwt.client.widgets.form.fields.PickerIcon;
                import com.smartgwt.client.widgets.form.fields.TextItem;
                import com.smartgwt.client.widgets.form.fields.events.IconClickEvent;
                import com.smartgwt.client.widgets.form.fields.events.IconClickHandler;
                
                
                public class ServerSideFilePicker extends TextItem {
                
                	private static Dialog dialog;
                	private static ServerSideFilePicker currentEditor;
                
                	/**
                	 * An optional filter used to limit the files displayed by this file picker. For example, can set to ".xls" to limit returned files to excel files. If is
                	 * null, no filtering done.
                	 */
                	private String fileFilter = null;
                
                	/**
                	 * Constructor
                	 * 
                	 * @param name name of this file picker form item
                	 * @param title String title to associate with this file picker
                	 * @param callingForm the calling form. Required for work-around to trigger change events on calling form when picker value is set programatically.
                	 */
                	public ServerSideFilePicker(String name, String title) {
                		super(name, title);
                		this.setWidth(400);
                		PickerIcon searchPicker = new PickerIcon(PickerIcon.SEARCH);
                		setIcons(searchPicker);
                		addIconClickHandler(new IconClickHandler() {
                			public void onIconClick(IconClickEvent event) {
                
                				// get global coordinates of the clicked picker icon
                				Rectangle iconRect = getIconPageRect(event.getIcon());
                
                				// remember what editor is active, so we can set its value from the picker dialog
                				ServerSideFilePicker.currentEditor = ServerSideFilePicker.this;
                
                				// get the current value of the text item. Send to the dialog as the current file to display
                				String directory = ServerSideFilePicker.currentEditor.getValueAsString();
                
                				// lazily create the the server side directory display dialog when the picker is first used
                				if (ServerSideFilePicker.dialog == null) {
                					dialog = new ServerSideFileDisplayDialog(directory, fileFilter);
                					dialog.setID("ServerSideFilePickerDialog");
                				} else {
                					// TODO send new criteria to dialog to change files displayed
                				}
                
                				// show the picker dialog
                				ServerSideFilePicker.showDialog(iconRect.getLeft(), iconRect.getTop());
                			}
                		});
                	}
                
                	public String getFileFilter() {
                		return fileFilter;
                	}
                
                	/**
                	 * A regular expression used to filter the files returned by this user interface.
                	 * 
                	 * @param fileFilter
                	 */
                	public void setFileFilter(String fileFilter) {
                		this.fileFilter = fileFilter;
                	}
                
                	// set the specified value and dismiss the picker dialog
                	protected static void setCurrentValue(String value) {
                		String oldVal = currentEditor.getValueAsString();
                		currentEditor.setValue(value);
                		dialog.hide();
                
                	}
                
                	
                
                	// show the picker dialog at the specified position
                	protected static void showDialog(int left, int top) {
                		dialog.show();
                		dialog.moveTo(left, top);
                	}
                
                	protected static void hideDialog() {
                		dialog.hide();
                	}
                
                }

                Comment


                  #9
                  I am still having the same problem on moduleLoad (not sure that was clear in my previous post).

                  Comment


                    #10
                    OK, we'll take a look, thanks for the test case.

                    Comment


                      #11
                      Will you guys indicate resolution on this issue, or should I just check nightly builds?

                      Comment


                        #12
                        We'll indicate resolution here.

                        Comment


                          #13
                          A quick update to note that we are still looking at exactly what's going on here but for you now you can workaround this by explicitly calling 'setDataSource()' on the DynamicForm as well as on the ValuesManager

                          Thanks
                          Isomorphic Software

                          ====
                          Update - we believe we've resolved the issue. Please try the next nightly build (Feb 1 or greater, on the 3.0p branch) and let us know if you continue to see it.
                          Last edited by Isomorphic; 31 Jan 2012, 15:14.

                          Comment


                            #14
                            I just downloaded the 2/2/12 nightly build. The problem is solved both for my test case and my much larger application.

                            Thanks!

                            Comment

                            Working...
                            X