here's the example from the Showcase:
Run the InlineScriptValidationSample and you can see that the FormItemValueFormatter.formatValue was never called.
Now change in this example final DynamicForm form = new CommonEditorForm(); to the DynamicForm and the formatter works as expected.
tested version is:
SmartClient Version: v9.0p_2014-04-27/PowerEdition Deployment (built 2014-04-27)
What is wrong in the CommonEditorForm which prevents the SelectItem from calling the FormItemValueFormatter.
Code:
/*
* Isomorphic SmartGWT web presentation layer
* Copyright 2000 and beyond Isomorphic Software, Inc.
*
* OWNERSHIP NOTICE
* Isomorphic Software owns and reserves all rights not expressly granted in this source code,
* including all intellectual property rights to the structure, sequence, and format of this code
* and to all designs, interfaces, algorithms, schema, protocols, and inventions expressed herein.
*
* If you have any questions, please email <sourcecode@isomorphic.com>.
*
* This entire comment must accompany any portion of Isomorphic Software source code that is
* copied or moved from this file.
*/
package com.smartgwt.sample.showcase.client.dataintegration.java.form;
import com.smartgwt.client.data.DataSource;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.FormItemValueFormatter;
import com.smartgwt.client.widgets.form.fields.ButtonItem;
import com.smartgwt.client.widgets.form.fields.ComboBoxItem;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.HeaderItem;
import com.smartgwt.client.widgets.form.fields.IntegerItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.TextAreaItem;
import com.smartgwt.sample.showcase.client.PanelFactory;
import com.smartgwt.sample.showcase.client.ShowcasePanel;
public class InlineScriptValidationSample extends ShowcasePanel {
private static final String DESCRIPTION =
"Use the \"Item Id\" ComboBox to select an item, enter a very large quantity (999999) "+
"and press the \"Submit Order\" button."+
"<P/>The resulting validation error is based upon a server-side condition specified in "+
"the validator using inline scripting. It checks a related DataSource "+
"(StockItem) to see if there is sufficient quantity in stock to fulfill the order.";
public static class Factory implements PanelFactory {
private String id;
public ShowcasePanel create() {
InlineScriptValidationSample panel = new InlineScriptValidationSample();
id = panel.getID();
return panel;
}
public String getID() {
return id;
}
public String getDescription() {
return DESCRIPTION;
}
}
public Canvas getViewPanel() {
final DynamicForm form = new CommonEditorForm();
DataSource dataSource = DataSource.get("inlineScript_orderForm");
form.setDataSource(dataSource);
HeaderItem header = new HeaderItem("header");
header.setDefaultValue("Add an item to your Order");
SelectItem item = new SelectItem("itemId", "Item 123");
item.setOptionDataSource(DataSource.get("StockItem"));
item.setValueField("id");
item.setDisplayField("description");
item.setRequired( true );
item.setAllowEmptyValue(true);
//tried cell formatters, but they do not work on the select or on pick items of this select
item.setEmptyPickListMessage("None");
item.setValueFormatter(new FormItemValueFormatter() {
@Override
public String formatValue(Object value, Record record,
DynamicForm form, FormItem item) {
System.out.println("ComboBoxItem Formatter is called");
if ( value != null) {
String v = value.toString() + "123";
return v;
}
return ""+(String)value+"123";
}
});
IntegerItem quantity = new IntegerItem("quantity");
quantity.setValidateOnExit(true);
TextAreaItem instructions = new TextAreaItem("instructions");
ButtonItem submit = new ButtonItem("submit", "Submit Order");
form.setFields(header, item, quantity, instructions, submit);
return form;
}
public String getIntro() {
return DESCRIPTION;
}
}
Code:
package com.smartgwt.sample.showcase.client.dataintegration.java.form;
public interface ItemWithDefaultValue {
public void setDefaultValue( String defaultValue );
public void fillDefaultValue();
public Object getDefault();
}
Code:
package com.smartgwt.sample.showcase.client.dataintegration.java.form;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.FormItemValueFormatter;
import com.smartgwt.client.widgets.form.fields.FormItem;
public class FormItemEscapeHtmlFormatter implements FormItemValueFormatter {
@Override
public String formatValue( final Object value, final Record record, final DynamicForm form,
final FormItem item ) {
return CommonHTMLEscapeFormatterUtil.format( value );
}
}
Code:
package com.smartgwt.sample.showcase.client.dataintegration.java.form;
import com.smartgwt.client.util.StringUtil;
public class CommonHTMLEscapeFormatterUtil {
static public String format( final Object value ) {
if ( value != null && value instanceof String ) {
final String valueString = (String)value;
final String escapedString = StringUtil.asHTML( valueString );
return escapedString;
}
return value == null ? null : value.toString();
}
}
Code:
package com.smartgwt.sample.showcase.client.dataintegration.java.form;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.FormErrorOrientation;
import com.smartgwt.client.util.StringUtil;
import com.smartgwt.client.widgets.form.DynamicForm;
import com.smartgwt.client.widgets.form.ValuesManager;
import com.smartgwt.client.widgets.form.fields.FormItem;
import com.smartgwt.client.widgets.form.fields.PasswordItem;
import com.smartgwt.client.widgets.form.fields.SelectItem;
import com.smartgwt.client.widgets.form.fields.StaticTextItem;
import com.smartgwt.client.widgets.grid.ListGridRecord;
/**
* Common class for creating editor forms.
* NOTE: This class does not support changing a required field to not required and enabled
*/
public class CommonEditorForm extends DynamicForm {
/** The filling list. */
private final List< ItemWithDefaultValue > fillingList = new ArrayList< ItemWithDefaultValue >();
/**
* Instantiates a new common editor form.
*/
public CommonEditorForm() {
this( null, null );
}
/**
* Instantiates a new common editor form.
*
* [USER="45788"]param[/USER] isGroup Should a grouping frame be shown around this canvas.
*/
public CommonEditorForm( final Boolean isGroup ) {
this( null, isGroup );
}
/**
* Instantiates a new common editor form.
*
* [USER="45788"]param[/USER] manager the manager
*/
public CommonEditorForm( final ValuesManager manager ) {
this( manager, null );
}
/**
* Instantiates a new common editor form.
*
* [USER="45788"]param[/USER] manager The values manager for managing multiple forms as one.
* [USER="45788"]param[/USER] isGroup Should a grouping frame be shown around this canvas.
*/
public CommonEditorForm( final ValuesManager manager, final Boolean isGroup ) {
super();
if ( isGroup != null ) {
super.setIsGroup( isGroup );
}
// If a values manager has been specified, then associate it with this class.
if ( null != manager ) {
this.setValuesManager( manager );
// //////////////////////////////////////////////////////////////////////////////////////////////////
// The SmartGWT documentation for setValuesManager states:
//
// "If specified at initialization time, this component will be added to the valuesManager
// via ValuesManager.addMember."
//
// However, this does not happen until after the form is drawn. Therefore, anything that creates
// a CommonEditorForm with a values manager and expects to retrieve a form item via the manager
// before the form has been drawn will get back a null value. To ensure that this form is
// in the manager immediately, also call addMember on the manager to add this form.
//
manager.addMember( this );
}
super.setWrapItemTitles( false );
super.setErrorOrientation( FormErrorOrientation.RIGHT );
super.setRequiredTitlePrefix( "" );
super.setRequiredTitleSuffix( " :" );
super.setTitlePrefix( "" );
super.setTitleSuffix( " :" );
super.setBrowserSpellCheck( false );
super.setShowErrorStyle( false );
}
/**
* Clear the form.
*/
public void clearForm() {
super.clearValues();
this.fillingList.clear();
for ( final FormItem formItem : this.getFields() ) {
if ( formItem instanceof PasswordItem ) {
formItem.clearValue();
}
}
super.rememberValues();
}
/**
* Update the form to display/edit the specified record.
*
* [USER="45788"]param[/USER] record the record to display/edit
*/
public void updateForm( final Record record ) {
if ( record != null ) {
final FormItem[] formItems = this.getFields();
for ( final FormItem formItem : formItems ) {
formItem.setValue( record.getAttribute( formItem.getName() ) );
}
super.clearErrors( true );
this.fillingList.clear();
super.rememberValues();
}
}
/**
* Gets the record associated with this form.
*
* @return the record associated with this form.
*/
public Record getData() {
return this.getData( new ListGridRecord() );
}
/**
* Gets the record associated with this form.
*
* [USER="45788"]param[/USER] record the record to fill in with the retrieved data
* @return the passed in record filled in with the retrieve data
*/
public Record getData( final Record record ) {
final FormItem[] formItems = super.getFields();
for ( final FormItem formItem : formItems ) {
if ( formItem.isDisabled() == true ) {
record.setAttribute( formItem.getName(), (Object)null );
} else {
record.setAttribute( formItem.getName(), formItem.getValue() );
}
}
super.rememberValues();
return record;
}
/**
* Adds the to filling list.
*
* [USER="45788"]param[/USER] items the items
*/
public void addToFillingList( final ItemWithDefaultValue... items ) {
if ( items == null ) {
return;
}
for ( final ItemWithDefaultValue item : items ) {
this.fillingList.add( item );
}
}
/**
* Clear filling list.
*/
public void clearFillingList() {
this.fillingList.clear();
}
/**
* Fill default values.
*
* [USER="45788"]param[/USER] fillAll whether or not to fill all items.
*/
public void fillDefaultValues( final boolean fillAll ) {
if ( fillAll == true ) {
final FormItem[] formItems = super.getFields();
for ( final FormItem formItem : formItems ) {
if ( formItem instanceof ItemWithDefaultValue ) {
( (ItemWithDefaultValue)formItem ).fillDefaultValue();
}
}
} else {
for ( final ItemWithDefaultValue item : this.fillingList ) {
item.fillDefaultValue();
}
}
super.rememberValues();
}
/*
* (non-Javadoc)
* [USER="61157"]see[/USER]
* com.smartgwt.client.widgets.form.DynamicForm#setFields(com.smartgwt.client.widgets.form.fields
* .FormItem[])
*/
@Override
public void setFields( final FormItem... fields ) {
if ( fields != null ) {
for ( final FormItem formItem : fields ) {
if ( null == formItem ) {
continue;
}
formItem.setRequiredMessage( "the_required_entry_field_is_blank" );
if ( null != formItem.getRequired() && formItem.getRequired() ) {
this.setTitleStyleWithAsterisk( formItem );
}
this.setEscapeFormatter( formItem );
}
}
super.setFields( fields );
}
/*
* (non-Javadoc)
* [USER="61157"]see[/USER] com.smartgwt.client.widgets.Canvas#setGroupTitle(java.lang.String)
*/
@Override
public void setGroupTitle( final String title ) {
if ( title == null ) {
return;
}
super.setGroupTitle( CommonHTMLEscapeFormatterUtil.format( title ) );
}
/**
* The fields to set on the forms.
*
* [USER="45788"]param[/USER] asteriskFields the asterisk fields are those that are required to be filled in by the end-user
* [USER="45788"]param[/USER] fields the fields non-required fields.
*/
public void setFields( final FormItem[] asteriskFields, final FormItem... fields ) {
if ( asteriskFields != null ) {
for ( final FormItem requiredFormItem : asteriskFields ) {
this.setTitleStyleWithAsterisk( requiredFormItem );
}
}
for ( final FormItem formItem : fields ) {
this.setEscapeFormatter( formItem );
formItem.setRequiredMessage( "the_required_entry_field_is_blank" );
}
super.setFields( fields );
}
/**
* enable/disable formitem when disable,set required false and clear field error.
*
* [USER="45788"]param[/USER] enable enable
* [USER="45788"]param[/USER] fields the form items
*/
public void enableFormItems( final boolean enable, final FormItem[] fields ) {
if ( enable ) {
for ( final FormItem formItem : fields ) {
formItem.setDisabled( false );
}
} else {
if ( fields != null ) {
for ( final FormItem formItem : fields ) {
formItem.setRequired( false );
formItem.setDisabled( true );
super.clearFieldErrors( formItem.getFieldName(), false );
}
}
}
}
/**
* Sets the enabled/disabled state of all form items in the form.
*
* [USER="45788"]param[/USER] enable true to enable all form items, false to disable all form items.
*/
public void setEnableAllFormItems( final boolean enable ) {
for ( FormItem formItem : this.getFields() ) {
formItem.setDisabled( !enable );
}
}
/**
* Sets the title style with asterisk.
*
* [USER="45788"]param[/USER] formItem the new title style with asterisk
*/
protected void setTitleStyleWithAsterisk( final FormItem formItem ) {
formItem.setTitle( formItem.getTitle() + "*" );
}
/**
* Validate.
*
* [USER="45788"]param[/USER] recordList the record list
* @return true, if successful
*/
public boolean validate( final Object recordList ) {
return true;
}
/**
* Sets the escape formatter.
*
* [USER="45788"]param[/USER] formItem the new escape formatter
*/
private void setEscapeFormatter( final FormItem formItem ) {
if ( ( formItem instanceof SelectItem ) || formItem instanceof StaticTextItem ) {
formItem.setValueFormatter( new FormItemEscapeHtmlFormatter() );
}
}
/**
* Convert a map of form item errors to a string.
*
* [USER="45788"]param[/USER] errors the map of form item errors
* @return the string
*/
@SuppressWarnings( "unchecked" )
private static String errorsToString( final Map< FormItem, Object > errors ) {
final StringBuilder builder = new StringBuilder();
for ( final FormItem item : errors.keySet() ) {
List< String > texts = new ArrayList< String >();
if ( errors.get( item ) instanceof List ) {
texts = (List< String >)errors.get( item );
} else {
texts.add( errors.get( item ).toString() );
}
if ( builder.length() > 0 ) {
builder.append( "; " );
}
if ( null != item.getTitle() ) {
if ( item.getTitle().endsWith( "*" ) ) {
builder.append( item.getTitle().substring( 0, item.getTitle().length() - 1 ) );
} else {
builder.append( item.getTitle() );
}
builder.append( ": " );
}
for ( int i = 0; i < texts.size(); i++ ) {
if ( i > 0 ) {
builder.append( ", " );
}
builder.append( texts.get( i ) );
}
}
return builder.toString();
}
/**
* Converts errors in the form items within the value manager into a string
*
* [USER="45788"]param[/USER] manager the manager containing the form items with errors
* @return the string
*/
public static String errorsToString( final ValuesManager manager ) {
@SuppressWarnings( "unchecked" )
final Map< String, String > errors = manager.getErrors();
final Map< FormItem, Object > result = new LinkedHashMap< FormItem, Object >();
for ( final String key : errors.keySet() ) {
final FormItem item = manager.getItem( key );
if ( null != item ) {
result.put( item, errors.get( key ) );
}
}
return CommonEditorForm.errorsToString( result );
}
/**
* Converts errors in the form items within the form into a string
*
* [USER="45788"]param[/USER] form the form
* @return the string
*/
public static String errorsToString( final DynamicForm form ) {
@SuppressWarnings( "unchecked" )
final Map< String, String > errors = form.getErrors();
final Map< FormItem, Object > result = new LinkedHashMap< FormItem, Object >();
for ( final String key : errors.keySet() ) {
final FormItem item = form.getItem( key );
if ( null != item ) {
result.put( item, errors.get( key ) );
}
}
return CommonEditorForm.errorsToString( result );
}
/*
* (non-Javadoc)
* [USER="61157"]see[/USER] com.smartgwt.client.widgets.form.DynamicForm#setValue(java.lang.String, java.lang.String)
*/
@Override
public void setValue( final String fieldName, final String value ) {
if ( fieldName == null ) {
super.setValue( fieldName, value );
}
if ( super.getItem( fieldName ) instanceof SelectItem ) {
final SelectItem item = (SelectItem)super.getItem( fieldName );
item.setValue( value );
return;
}
super.setValue( fieldName, value );
}
}
Now change in this example final DynamicForm form = new CommonEditorForm(); to the DynamicForm and the formatter works as expected.
tested version is:
SmartClient Version: v9.0p_2014-04-27/PowerEdition Deployment (built 2014-04-27)
What is wrong in the CommonEditorForm which prevents the SelectItem from calling the FormItemValueFormatter.
Comment