|
#1
|
|||
|
|||
|
I'm trying to build a custom TextItem for use in both a Form and a FilterBuilder. This TextItem has a FormItemIcon that when clicked brings up a canvas with a field on it, and a save and cancel button. The save button has a callback on it that tries to set the value of the field on the canvas as the value of the custom TextItem. When using this on a form, it works fine, but when using it as the EditorType on a DataSourceTextField used by a FilterBuilder the value doesn't get set, and when I call getValue() on the TextItem, I get the Java Script Error below.
I posted about a very similar problem with a custom editor on a ListGrid here: http://forums.smartclient.com/showthread.php?t=13032 I've built a test case based on the CustomDS example. After the JavaScript error is the code and also attached. I'm running with the nightly build of SmartGWT Pro from Sep 9, 2010 on Firefox 3.6.10 on XP SP3. Thanks for your help. JavaScript: Code:
Uncaught exception escaped : com.google.gwt.core.client.JavaScriptException
(TypeError): self.getValue is not a function
fileName: http://127.0.0.1:8888
lineNumber: 352
stack: ()@http://127.0.0.1:8888:352
@:0
([object GWTJavaObject],3014818,[object GWTJavaObject])@http://127.0.0.1:8888/customds/hosted.html?customds:56
([object Object],(void 0))@http://127.0.0.1:8888:1434
((function () {var param = {};var event = __gwt_makeJavaInvoke(1)(null, 5242919, param);__gwt_makeJavaInvoke(1)(selfJ, 3014818, event);var ret = __gwt_makeJavaInvoke(0)(event, 1179649);return !ret;}),[object Object],[object Object])@http://127.0.0.1:8888:6
@:0
(null,65563,(function () {var param = {};var event = __gwt_makeJavaInvoke(1)(null, 5242919, param);__gwt_makeJavaInvoke(1)(selfJ, 3014818, event);var ret = __gwt_makeJavaInvoke(0)(event, 1179649);return !ret;}),[object Object],[object Object])@http://127.0.0.1:8888/customds/hosted.html?customds:56
([object Object],(void 0))@http://127.0.0.1:8888:41
([object Object],(void 0))@http://127.0.0.1:8888:13
isc_StatefulCanvas_handleActivate([object Object],(void 0))@http://127.0.0.1:8888/customds/sc/modules/ISC_Foundation.js:318
isc_StatefulCanvas_handleClick([object Object],(void 0))@http://127.0.0.1:8888/customds/sc/modules/ISC_Foundation.js:320
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
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.fields.DataSourceBooleanField;
import com.smartgwt.client.data.fields.DataSourceDateField;
import com.smartgwt.client.data.fields.DataSourceFloatField;
import com.smartgwt.client.data.fields.DataSourceSequenceField;
import com.smartgwt.client.data.fields.DataSourceTextField;
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.form.DynamicForm;
import com.smartgwt.client.widgets.form.FilterBuilder;
import com.smartgwt.client.widgets.layout.VStack;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class CustomDS implements EntryPoint
{
/**
* 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 );
FilterBuilder filterBuilder = new FilterBuilder();
filterBuilder.setDataSource( dataSource );
vStack.addMember( filterBuilder );
DynamicForm form = new DynamicForm();
CustomTextItem itemField = new CustomTextItem();
itemField.setTitle( "Item" );
form.setFields( itemField );
vStack.addMember( form );
vStack.draw();
}
}
Code:
package com.smartgwt.sample.client;
import com.smartgwt.client.util.EventHandler;
import com.smartgwt.client.widgets.form.fields.FormItem;
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
{
private CustomCanvas customCanvas;
public CustomTextItem()
{
FormItemIcon formItemIcon = new FormItemIcon();
setIcons( formItemIcon );
customCanvas = new CustomCanvas();
addIconClickHandler( new IconClickHandler()
{
@Override
public void onIconClick(IconClickEvent event)
{
System.out.println( "getValue() is " + event.getItem().getValue() );
FormItem formItem = event.getItem();
customCanvas.setValue( (String) formItem.getValue() );
customCanvas.setTop( EventHandler.getY() );
customCanvas.setLeft( EventHandler.getX() );
customCanvas.show();
customCanvas.bringToFront();
}
} );
customCanvas.registerCancelHandler( new ClickCallback()
{
@Override
public void onClick()
{
customCanvas.hide();
}
} );
customCanvas.registerSaveHandler( new CustomTextItemCallback( CustomTextItem.this ) );
}
public class CustomTextItemCallback implements ObjectCallback
{
CustomTextItem myCustomTextItem;
public CustomTextItemCallback(CustomTextItem customTextItem)
{
myCustomTextItem = customTextItem;
}
@Override
public void execute(Object value)
{
customCanvas.hide();
System.out.println( "CustomTextItem, value = " + value );
myCustomTextItem.setValue( (String) value );
System.out.println( "myCustomTextItem.getValue() = " + myCustomTextItem.getValue() );
}
}
}
Code:
package com.smartgwt.sample.client;
import com.google.gwt.event.shared.HandlerRegistration;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.IButton;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
public class CustomCanvas extends Canvas
{
private TextItem item;
IButton saveButton;
final IButton cancelButton;
public CustomCanvas()
{
super( );
this.setBackgroundColor( "#FFFFFF" );
this.setBorder( "2px solid" );
this.setWidth( 255 );
this.setHeight( 100 );
VLayout vlayout = new VLayout( 10 );
vlayout.setPadding( 10 );
DynamicForm itemForm = new DynamicForm();
itemForm.setWidth( "100%" );
item = new TextItem();
item.setTitle( "Item" );
item.setWidth( 200 );
itemForm.setItems( item );
vlayout.addMember( itemForm );
HLayout hlayout = new HLayout();
hlayout.setWidth( 255 );
hlayout.setAlign( Alignment.CENTER );
saveButton = new IButton( "Save" );
cancelButton = new IButton( "Cancel" );
DynamicForm spacer1 = new DynamicForm();
spacer1.setWidth( 10 );
hlayout.addMember( saveButton );
hlayout.addMember( spacer1 );
hlayout.addMember( cancelButton );
vlayout.addMember( hlayout );
addChild( vlayout );
}
public HandlerRegistration registerSaveHandler(final ObjectCallback callback)
{
return saveButton.addClickHandler( new ClickHandler()
{
public void onClick(com.smartgwt.client.widgets.events.ClickEvent event)
{
String value = ((String)item.getValue()) + " plus a modification.";
callback.execute( value );
}
} );
}
public HandlerRegistration registerCancelHandler(final ClickCallback callback)
{
return cancelButton.addClickHandler( new ClickHandler()
{
public void onClick(com.smartgwt.client.widgets.events.ClickEvent event)
{
callback.onClick();
}
} );
}
/**
* @param value
*/
public void setValue(String value)
{
item.setValue( value );
}
}
Code:
package com.smartgwt.sample.client;
public interface ObjectCallback
{
void execute(Object value);
}
Code:
package com.smartgwt.sample.client;
public interface ClickCallback
{
void onClick();
}
|
|
#2
|
|||
|
|||
|
Any feedback on this? - I am also interested in a resolution.
|
|
#3
|
|||
|
|||
|
So the DynamicForm works and calling getValue() on the CustomTextItem also returns the correct value. You're only having an issue with FilterBuilder, right?
Can you post a screenshot of sample because it appears from your description that you are seeing your custom text item in the FilterBuilder while I'm not. Sanjiv |
|
#4
|
|||
|
|||
|
Thanks Sanjiv. You have it correct, I'm only having the issue with a FilterBuilder.
Attached are a screen shot of the FilterBuilder using the CustomTextItem, about to save a value. The next screen shot is the resulting JavaScriptException after the Save button has been clicked. |
|
#5
|
|||
|
|||
|
The problem with the original code had the call to
Code:
customCanvas.registerSaveHandler( new CustomTextItemCallback( CustomTextItem.this ) ); Quote:
Here's the updated code : Code:
import com.smartgwt.client.util.EventHandler;
import com.smartgwt.client.widgets.form.fields.FormItem;
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();
setIcons(formItemIcon);
addIconClickHandler(new IconClickHandler() {
@Override
public void onIconClick(IconClickEvent event) {
FormItem formItem = event.getItem();
System.out.println("getValue() is " + event.getItem().getValue());
CustomCanvas customCanvas = new CustomCanvas(formItem);
customCanvas.setTop(EventHandler.getY());
customCanvas.setLeft(EventHandler.getX());
customCanvas.show();
customCanvas.bringToFront();
}
});
}
}
Code:
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.IButton;
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.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.TextItem;
import com.smartgwt.client.widgets.layout.HLayout;
import com.smartgwt.client.widgets.layout.VLayout;
public class CustomCanvas extends Canvas {
public CustomCanvas(final FormItem filterBuilderFormItem) {
super();
this.setBackgroundColor("#FFFFFF");
this.setBorder("2px solid");
this.setWidth(255);
this.setHeight(100);
VLayout vlayout = new VLayout(10);
vlayout.setPadding(10);
DynamicForm itemForm = new DynamicForm();
itemForm.setWidth("100%");
final TextItem item = new TextItem();
item.setTitle("Item");
item.setWidth(200);
itemForm.setItems(item);
vlayout.addMember(itemForm);
HLayout hlayout = new HLayout();
hlayout.setWidth(255);
hlayout.setAlign(Alignment.CENTER);
IButton saveButton = new IButton("Save");
IButton cancelButton = new IButton("Cancel");
DynamicForm spacer1 = new DynamicForm();
spacer1.setWidth(10);
hlayout.addMember(saveButton);
hlayout.addMember(spacer1);
hlayout.addMember(cancelButton);
vlayout.addMember(hlayout);
addChild(vlayout);
item.setValue((String) filterBuilderFormItem.getValue());
saveButton.addClickHandler(new ClickHandler() {
public void onClick(com.smartgwt.client.widgets.events.ClickEvent event) {
String value = ((String) item.getValue()) + " plus a modification.";
filterBuilderFormItem.setValue(value);
CustomCanvas.this.hide();
}
});
cancelButton.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
CustomCanvas.this.hide();
}
});
}
}
The CustomDS EntryPoint class remains unchanged. Note that when I initially ran your test I was simply getting a text field show without the CustomTextItem properties being applied despite itemName.setEditorType(new CustomTextItem()) being called. A fix was made to resolve this but its still unclear how it did apply for you as shown in your screenshot. Anyways if you do run into this, then pick up the next nightly build. Sanjiv |
|
#6
|
|||
|
|||
|
It didn't really sink into my head that when you call setEditorType on the FilterBuilder with an object, you are really using the properties and type of that object, not the actual instance. It seems counter-intuitive.
What you have shown to do here worked for me in my real-world code. Thanks Sanjiv for your for help and advice. I'm not sure why my original example worked for me, but not for you. I was running the SmartGWT Pro nightly build from September 10th. Nevertheless, my problem is fixed. Thank you! |