Announcement

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

    problem with using custom editor in ListGrid: JS crash on getValue()

    Hi all,

    I am having trouble using a custom editor in a grid.

    (The editor is a subclass of StaticTextItem, with some added icons from functionality.)

    The editor works OK when using in a DynamicForm, but I can not get it to work in ListGrids.

    I am passing in the editor by calling setEditorType() on the relevant ListGridField.

    When starting to edit, the editor is displayed OK (with the right value), but wget when calling getValue() in one of the icon click handlers, I get a JS exception:

    Code:
    Error: com.google.gwt.core.client.JavaScriptException: (TypeError): self.getValue is not a function
     fileName: http://127.0.0.1:8888
     lineNumber: 486
     stack: ()@http://127.0.0.1:8888:486
    @:0
    ([object GWTJavaObject],4325431,[object GWTJavaObject])@http://127.0.0.1:8888/orgtel/hosted.html?orgtel:56
    ([object Object],[object Object],[object Object])@http://127.0.0.1:8888:15
    ((function () {var param = {form: arguments[0], item: arguments[1], icon: arguments[2]};var event = __gwt_makeJavaInvoke(1)(null, 13500445, param);__gwt_makeJavaInvoke(1)(selfJ, 4325431, event);}),[object Object],[object Object])@http://127.0.0.1:8888:12
    @:0
    (null,65563,(function () {var param = {form: arguments[0], item: arguments[1], icon: arguments[2]};var event = __gwt_makeJavaInvoke(1)(null, 13500445, param);__gwt_makeJavaInvoke(1)(selfJ, 4325431, event);}),[object Object],[object Object])@http://127.0.0.1:8888/orgtel/hosted.html?orgtel:56
    ([object Object],[object Object],[object Object])@http://127.0.0.1:8888:36
    isc_FormItem__iconClick("_0")@http://127.0.0.1:8888/orgtel/sc/modules/ISC_Forms.js:1382
    isc_DynamicForm_handleClick([object Object],(void 0))@http://127.0.0.1:8888/orgtel/sc/modules/ISC_Forms.js:650
    isc_c_EventHandler_bubbleEvent([object Object],"click")@http://127.0.0.1:8888/orgtel/sc/modules/ISC_Core.js:1536
    isc_c_EventHandler_handleClick([object Object])@http://127.0.0.1:8888/orgtel/sc/modules/ISC_Core.js:1389
    isc_c_EventHandler__handleMouseUp([object MouseEvent],(void 0))@http://127.0.0.1:8888/orgtel/sc/modules/ISC_Core.js:1376
    isc_c_EventHandler_handleMouseUp([object MouseEvent])@http://127.0.0.1:8888/orgtel/sc/modules/ISC_Core.js:1367
    isc_c_EventHandler_dispatch(isc_c_EventHandler_handleMouseUp,[object MouseEvent])@http://127.0.0.1:8888/orgtel/sc/modules/ISC_Core.js:1599
    anonymous([object MouseEvent])@http://127.0.0.1:8888/orgtel/sc/modules/ISC_Core.js:61
    
    	com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:195)
    	com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:120)
    	com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:507)
    	com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:264)
    	com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
    	com.smartgwt.client.widgets.form.fields.FormItem.getValue(FormItem.java)
    	com.nolmecolindor.sgweet.client.widgets.data.linking.EntityLinkItem$3$1.onFormItemClickChecked(EntityLinkItem.java:69)
    	com.nolmecolindor.sgweet.client.errorhandling.CheckedFormItemClickHandler.onFormItemClick(CheckedFormItemClickHandler.java:10)
    	com.smartgwt.client.widgets.form.fields.events.FormItemIconClickEvent.dispatch(FormItemIconClickEvent.java:95)
    	com.smartgwt.client.widgets.form.fields.events.FormItemIconClickEvent.dispatch(FormItemIconClickEvent.java:1)
    	com.google.gwt.event.shared.HandlerManager$HandlerRegistry.fireEvent(HandlerManager.java:65)
    	com.google.gwt.event.shared.HandlerManager$HandlerRegistry.access$1(HandlerManager.java:53)
    	com.google.gwt.event.shared.HandlerManager.fireEvent(HandlerManager.java:178)
    	com.smartgwt.client.core.DataClass.fireEvent(DataClass.java:197)
    	sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    	sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	java.lang.reflect.Method.invoke(Method.java:597)
    	com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
    	com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    	com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:157)
    	com.google.gwt.dev.shell.BrowserChannel.reactToMessagesWhileWaitingForReturn(BrowserChannel.java:1714)
    	com.google.gwt.dev.shell.BrowserChannelServer.invokeJavascript(BrowserChannelServer.java:165)
    	com.google.gwt.dev.shell.ModuleSpaceOOPHM.doInvoke(ModuleSpaceOOPHM.java:120)
    	com.google.gwt.dev.shell.ModuleSpace.invokeNative(ModuleSpace.java:507)
    	com.google.gwt.dev.shell.ModuleSpace.invokeNativeObject(ModuleSpace.java:264)
    	com.google.gwt.dev.shell.JavaScriptHost.invokeNativeObject(JavaScriptHost.java:91)
    	com.google.gwt.core.client.impl.Impl.apply(Impl.java)
    	com.google.gwt.core.client.impl.Impl.entry0(Impl.java:188)
    	sun.reflect.GeneratedMethodAccessor528.invoke(Unknown Source)
    	sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    	java.lang.reflect.Method.invoke(Method.java:597)
    	com.google.gwt.dev.shell.MethodAdaptor.invoke(MethodAdaptor.java:103)
    	com.google.gwt.dev.shell.MethodDispatch.invoke(MethodDispatch.java:71)
    	com.google.gwt.dev.shell.OophmSessionHandler.invoke(OophmSessionHandler.java:157)
    	com.google.gwt.dev.shell.BrowserChannel.reactToMessages(BrowserChannel.java:1669)
    	com.google.gwt.dev.shell.BrowserChannelServer.processConnection(BrowserChannelServer.java:401)
    	com.google.gwt.dev.shell.BrowserChannelServer.run(BrowserChannelServer.java:222)
    	java.lang.Thread.run(Thread.java:619)
    Could you please help me what am I doing wrong?

    (From the standpoint of implementing custom editors, what is the difference between using custom editors in ListGrids and DynamicForms?)

    (This is SmartGWT-Power 2.3, FF 3.6, Linux)

    #2
    I can work around this by storing a pointer to the ListGrid in my custom editor, and then asking the grid for the current (edited) value, but this is surely not the intended usage.

    Comment


      #3
      More problems with the custom editor in the ListGrid.

      Now that I have a workaround to read out the current data, I find that when I modify it (via one of the controls), and save it back with setValue(),
      the displayed value is not updated.

      (I have a valueFormatter in place, but it's not called.)

      * * *

      The annoying thing is that I managed to get all these interactions right when using this editor as a part of the DynamicForm, but now it seems that interaction with a ListGrid is different.

      However, when configuring the editor for a ListGridField (via setEditorType), I am supposed to specify a FormItem, so I thought the same thing will work here, too. I was obviously wrong.

      Is there an example how to properly implement custom editors, which work well both with ListGrids and DynamicForms?

      Thank you for your help!

      Comment


        #4
        I got it working this way:

        1. When creating the custom editor, I store a pointer to the ListGrid.
        2. When needing the current value, I use ListGrid.getEditedCell() to read out the current value.
        3. When modified, I use ListGrid.setEditValue() to save back the value.

        This seems to work fine, but feels somewhat weird. (Especially having to readh the ListGrid manually, despite being an editor inside it, and having to pass the row number, which I look up based on the selection, which is no entirely correct, since edited row does not necessarily equals the selected row.)

        Is this the right approach?

        Thank you for your help!

        Comment


          #5
          I'm having the same Java Script Exceptions when I use a custom FormItem as the EditorType in a DataSourceTextField.

          Is there something that must be done to make a custom FormItem work as an Editor?

          Comment


            #6
            We've not seen this problem, waiting for someone to post a reproducible case.

            Comment


              #7
              Here is a reproducible test case: I took the CustomDS example, and created an additional custom FormItem called CustomTextItem that has an IconClickHandler on it. I then used it to set the EditorType on the itemName field. If you double click on an Item Field in the list grid to enable the editor, and then click on the icon, you'll get the java script exception.

              CustomTextItem.java:
              Code:
              package com.smartgwt.sample.client;
              
              import com.smartgwt.client.widgets.form.fields.FormItemIcon;
              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 CustomTextItem extends TextItem
              {
              
              	public CustomTextItem()
              	{
              		FormItemIcon formItemIcon = new FormItemIcon();
              		formItemIcon.setSrc( "[SKIN]DynamicForm/date_control.png" );
              		setIcons( formItemIcon );
              		
              		addIconClickHandler( new IconClickHandler()
              		{			
              			@Override
              			public void onIconClick(IconClickEvent event)
              			{
              				System.out.println("getValue() is " + getValue());
              			}
              		});
              	}
              
              }
              CustomDS.java
              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.data.Record;
              import com.smartgwt.client.data.fields.*;
              import com.smartgwt.client.types.CharacterCasing;
              import com.smartgwt.client.util.KeyCallback;
              import com.smartgwt.client.util.Page;
              import com.smartgwt.client.util.SC;
              import com.smartgwt.client.widgets.IButton;
              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.form.DynamicForm;
              import com.smartgwt.client.widgets.grid.ListGrid;
              import com.smartgwt.client.widgets.grid.ListGridRecord;
              import com.smartgwt.client.widgets.grid.events.RecordClickEvent;
              import com.smartgwt.client.widgets.grid.events.RecordClickHandler;
              import com.smartgwt.client.widgets.layout.VStack;
              import com.smartgwt.client.widgets.toolbar.ToolStrip;
              import com.smartgwt.client.widgets.viewer.DetailViewer;
              
              /**
               * Entry point classes define <code>onModuleLoad()</code>.
               */
              public class CustomDS implements EntryPoint {
                  private ListGrid boundList;
                  private DynamicForm boundForm;
                  private IButton saveBtn;
                  private DetailViewer boundViewer;
                  private IButton newBtn;
              
                  /**
                   * This is the entry point method.
                   */
                  public void onModuleLoad() {
              
                      
              		KeyIdentifier debugKey = new KeyIdentifier();
              		debugKey.setCtrlKey(true);
              		debugKey.setKeyName("D");
              
              		Page.registerKey(debugKey, new KeyCallback() {
              			public void execute(String keyName) {
              				SC.showConsole();
              			}
              		});
              
                      // instantiate DataSource on the client only (this example explicitly bypasses
                      // ISC server-side DataSource management)
              
                      DataSource dataSource = new DataSource();
                      dataSource.setDataURL(GWT.getModuleBaseURL() + "/supplyItemOperations.rpc");
                      dataSource.setID("supplyItem");
              
                      DataSourceSequenceField itemID = new DataSourceSequenceField("itemID");
                      itemID.setPrimaryKey(true);
                      itemID.setHidden(true);
              
                      DataSourceTextField itemName = new DataSourceTextField("itemName", "Item", 128, true);
                      CustomTextItem cti = new CustomTextItem();
                      cti.setCharacterCasing( CharacterCasing.UPPER );
                      itemName.setEditorType( cti );
              
                      DataSourceTextField SKU = new DataSourceTextField("SKU", "SKU", 10);
                      //SKU.setCanFilter(false);
              
                      DataSourceTextField description = new DataSourceTextField("description", "Description");        
                      DataSourceTextField category = new DataSourceTextField("category", "Category", 128);
                      DataSourceTextField units = new DataSourceTextField("units", "Units", 5);
              
                      DataSourceFloatField unitCost = new DataSourceFloatField("unitCost", "Unit Cost");
                      DataSourceBooleanField inStock = new DataSourceBooleanField("inStock", "In Stock");
              
                      DataSourceDateField nextShipment = new DataSourceDateField("nextShipment", "Next Shipment");
              
                      dataSource.setFields(itemID, itemName, SKU, description, category, units, unitCost, inStock, nextShipment);
              
              
                      VStack vStack = new VStack();
                      vStack.setLeft(175);
                      vStack.setTop(75);
                      vStack.setWidth("70%");
                      vStack.setMembersMargin(20);
              
                      Label label = new Label();
                      label.setContents("<ul>" +
                              "<li>click a record in the grid to view and edit that record in the form</li>" +
                              "<li>click <b>New</b> to start editing a new record in the form</li>" +
                              "<li>click <b>Save</b> to save changes to a new or edited record in the form</li>" +
                              "<li>click <b>Clear</b> to clear all fields in the form</li>" +
                              "<li>click <b>Filter</b> to filter (substring match) the grid based on form values</li>" +
                              "<li>click <b>Fetch</b> to fetch records (exact match) for the grid based on form values</li>" +
                              "<li>double-click a record in the grid to edit inline (press Return, or arrow/tab to another record, to save)</li>" +
                              "</ul>");
                      vStack.addMember(label);
              
                      boundList = new ListGrid();
                      boundList.setHeight(200);
                      boundList.setCanEdit(true);
                      boundList.setDataSource(dataSource);
              
                      boundList.addRecordClickHandler(new RecordClickHandler() {
                          public void onRecordClick(RecordClickEvent event) {
                              Record record = event.getRecord();
                              boundForm.editRecord(record);
                              saveBtn.enable();
                              boundViewer.viewSelectedData(boundList);
                          }
                      });
                      vStack.addMember(boundList);
              
                      boundForm = new DynamicForm();
                      boundForm.setDataSource(dataSource);
                      boundForm.setNumCols(6);
                      boundForm.setAutoFocus(false);
                      vStack.addMember(boundForm);
              
                      ToolStrip toolbar = new ToolStrip();
                      toolbar.setMembersMargin(10);
                      toolbar.setHeight(22);
              
                      saveBtn = new IButton("Save");
                      saveBtn.addClickHandler(new ClickHandler() {
                          public void onClick(ClickEvent event) {
                              boundForm.saveData();
                              if (!boundForm.hasErrors()) {
                                  boundForm.clearValues();
                                  saveBtn.disable();
                              }
                          }
                      });
                      toolbar.addMember(saveBtn);
              
                      IButton clearBtn = new IButton("Clear");
                      clearBtn.addClickHandler(new ClickHandler() {
                          public void onClick(ClickEvent event) {
                              boundForm.clearValues();
                              saveBtn.disable();
                          }
                      });
                      toolbar.addMember(clearBtn);
              
                      IButton filterBtn = new IButton("Filter");
                      filterBtn.addClickHandler(new ClickHandler() {
                          public void onClick(ClickEvent event) {
                              boundList.filterData(boundForm.getValuesAsCriteria());
                              saveBtn.disable();
                          }
                      });
                      toolbar.addMember(filterBtn);
              
                      IButton fetchBtn = new IButton("Fetch");
                      fetchBtn.addClickHandler(new ClickHandler() {
                          public void onClick(ClickEvent event) {
                              boundList.fetchData(boundForm.getValuesAsCriteria());
                              saveBtn.disable();
                          }
                      });
                      toolbar.addMember(fetchBtn);
              
                      IButton deleteBtn = new IButton("Delete");
                      deleteBtn.addClickHandler(new ClickHandler() {
                          public void onClick(ClickEvent event) {
                              boundList.removeSelectedData();
                              boundList.deselectAllRecords();
                          }
                      });
                      toolbar.addMember(deleteBtn);
              
                      vStack.addMember(toolbar);
              
                      boundViewer = new DetailViewer();
                      boundViewer.setDataSource(dataSource);
                      vStack.addMember(boundViewer);
              
                      vStack.draw();
              
                      boundList.filterData(null);
                  }
              
              }
              And the resulting exception:
              Code:
              13:45:44.561 [ERROR] [customds] Uncaught exception escaped
              com.google.gwt.core.client.JavaScriptException: (TypeError): self.getValue is not a function
               fileName: http://127.0.0.1:8888
               lineNumber: 555
               stack: ()@http://127.0.0.1:8888:555
              @:0
              ([object GWTJavaObject],655415,[object GWTJavaObject])@http://127.0.0.1:8888/customds/hosted.html?customds:56
              ([object Object],[object Object],[object Object])@http://127.0.0.1:8888:478
              ((function () {var param = {form: arguments[0], item: arguments[1], icon: arguments[2]};var event = __gwt_makeJavaInvoke(1)(null, 2097181, param);__gwt_makeJavaInvoke(1)(selfJ, 655415, event);}),[object Object],[object Object])@http://127.0.0.1:8888:23
              @:0
              (null,65563,(function () {var param = {form: arguments[0], item: arguments[1], icon: arguments[2]};var event = __gwt_makeJavaInvoke(1)(null, 2097181, param);__gwt_makeJavaInvoke(1)(selfJ, 655415, event);}),[object Object],[object Object])@http://127.0.0.1:8888/customds/hosted.html?customds:56
              ([object Object],[object Object],[object Object])@http://127.0.0.1:8888:47
              isc_FormItem__iconClick("_0")@http://127.0.0.1:8888/customds/sc/modules/ISC_Forms.js:1382
              isc_DynamicForm_handleClick([object Object],(void 0))@http://127.0.0.1:8888/customds/sc/modules/ISC_Forms.js:649
              isc_c_EventHandler_bubbleEvent([object Object],"click")@http://127.0.0.1:8888/customds/sc/modules/ISC_Core.js:1539
              isc_c_EventHandler_handleClick([object Object])@http://127.0.0.1:8888/customds/sc/modules/ISC_Core.js:1392
              isc_c_EventHandler__handleMouseUp([object MouseEvent],(void 0))@http://127.0.0.1:8888/customds/sc/modules/ISC_Core.js:1379
              isc_c_EventHandler_handleMouseUp([object MouseEvent])@http://127.0.0.1:8888/customds/sc/modules/ISC_Core.js:1370
              isc_c_EventHandler_dispatch(isc_c_EventHandler_handleMouseUp,[object MouseEvent])@http://127.0.0.1:8888/customds/sc/modules/ISC_Core.js:1602
              anonymous([object MouseEvent])@http://127.0.0.1:8888/customds/sc/modules/ISC_Core.js:60
              TIA for your feedback,
              Chris

              Comment


                #8
                When you supply a custom FormItem via setEditorType(), you're really providing properties which are then used to create multiple FormItems (eg, in grids, forms and trees) and there's an underlying limitation here where event handlers have to be written to dynamically receive the actual FormItem rather than relying on "this" (because there's more than one "this"). Here's a different way to write your CustomTextItem that works:

                Code:
                public class CustomTextItem extends TextItem
                {
                
                       public CustomTextItem()
                       {
                               FormItemIcon formItemIcon = new FormItemIcon();
                               formItemIcon.setSrc( "[SKIN]DynamicForm/date_control.png" );
                               setIcons( formItemIcon );
                               
                               addIconClickHandler( new IconClickHandler()
                               {                       
                                       @Override
                                       public void onIconClick(IconClickEvent event)
                                       {
                                               //System.out.println("getValue() is " + getValue());
                                               FormItem formItem = event.getItem();
                                               System.out.println("getValue() is " + formItem.getValue());
                                       }
                               });
                       }
                }

                Comment


                  #9
                  Thanks Isomorphic. That does solve the problem in a list grid. I'm having a similar problem setting the editorType on a DataSource field used in a FilterBuilder. I'll post a new thread with a code example.

                  Thanks again.

                  Comment

                  Working...
                  X