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