I've got a form that supports two different methods of data entry (manual and range based). Users can't switch the entry method by selecting one of two radio buttons. I've implemented this by putting two forms inside a layout and putting an onChangeHandler() on the radio buttons. As the users selects one radio option or the other; the appropriate form is hidden/made visible again.
Now, depending on which entry method is actually selected, certainly fields are required; but if the other entry method is selected, they are not required.
I figured I could solve this with a RequiredIfValidator; I check the value of the radioButton and return true or false in the RequiredIfFunction accordingly.
This works fine the first time each form renders; i.e. when form 1 renders, the correct fields are set as required and when I then select form 2, the other fields are selected as required as well.
However, when I now switch back to form 1, the fields no longer appear as required. Same when I switch back to form 2 again. I assume this is because the RequiredIfExpression is only evaluate once...
I've tried forcing a redraw on the form and/or the individual formitems but that had no result either.
Any ideas?
Relevant pieces of code below.
Validators:
Form instantiation:
Logic for handling switching of entry methods:
Full Source code:
Now, depending on which entry method is actually selected, certainly fields are required; but if the other entry method is selected, they are not required.
I figured I could solve this with a RequiredIfValidator; I check the value of the radioButton and return true or false in the RequiredIfFunction accordingly.
This works fine the first time each form renders; i.e. when form 1 renders, the correct fields are set as required and when I then select form 2, the other fields are selected as required as well.
However, when I now switch back to form 1, the fields no longer appear as required. Same when I switch back to form 2 again. I assume this is because the RequiredIfExpression is only evaluate once...
I've tried forcing a redraw on the form and/or the individual formitems but that had no result either.
Any ideas?
Relevant pieces of code below.
Validators:
Code:
public class RangeValidator extends RequiredIfValidator { public RangeValidator() { super(); this.setExpression(new RequiredIfFunction(){ @Override public boolean execute(FormItem formItem, Object value) { if(wizardForm.entryMethod.getValue().equals(EntryMethod.RANGE_ENTRY.toString())) { return true; } else { return false; } } }); } } public class ManualValidator extends RequiredIfValidator { public ManualValidator() { super(); this.setExpression(new RequiredIfFunction(){ @Override public boolean execute(FormItem formItem, Object value) { if(wizardForm.entryMethod.getValue().equals(EntryMethod.MANUAL.toString())) { return true; } else { return false; } } }); } }
Code:
entryMethodForm = new DynamicForm(); leftRangeEntryForm = new DynamicForm(); leftManualEntryForm = new DynamicForm(); entryMethod = new RadioGroupItem(DIDWizardField.ENTRY_METHOD.getName()); entryMethod.setTitle(DIDWizardField.ENTRY_METHOD.getDisplayTitle()); entryMethod.setValueMap(EntryMethod.getValueMap()); entryMethod.setVertical(false); entryMethod.setWrap(false); entryMethod.setDefaultValue(EntryMethod.RANGE_ENTRY.toString()); country=new ComboBoxItem(DIDWizardField.COUNTRY_ID.getName()); country.setTitle(DIDWizardField.COUNTRY_ID.getDisplayTitle()); country.setColSpan(4); country.setOptionDataSource(countryDS); country.setValueField(CountryField.COUNTRY_ID.getName()); country.setDisplayField(CountryField.COUNTRY_NAME.getName()); country.setOptionOperationId("filtered"); country.setAutoFetchData(true); country.setValidators(new RangeValidator()); ListGridField countryFlag = new ListGridField(CountryField.COUNTRY_CODE.getName(), "Flag", 30); countryFlag.setType(ListGridFieldType.IMAGE); countryFlag.setImageURLPrefix("flags/16/"); countryFlag.setImageURLSuffix(".png"); ListGridField countryName = new ListGridField(CountryField.COUNTRY_NAME.getName(), CountryField.COUNTRY_NAME.getDisplayTitle()); country.setPickListFields(countryFlag, countryName); npa = new TextItem(DIDWizardField.NPA.getName()); npa.setTitle(DIDWizardField.NPA.getDisplayTitle()); npa.setWidth(50); npa.setValidators(new RangeValidator()); nxx = new TextItem(DIDWizardField.NXX.getName()); nxx.setTitle(DIDWizardField.NXX.getDisplayTitle()); nxx.setWidth(50); nxx.setValidators(new RangeValidator()); extensionFrom = new TextItem(DIDWizardField.EXTENSION_FROM.getName()); extensionFrom.setTitle(DIDWizardField.EXTENSION_FROM.getDisplayTitle()); extensionFrom.setWidth(50); extensionFrom.setValidators(new RangeValidator()); extensionTo = new TextItem(DIDWizardField.EXTENSION_TO.getName()); extensionTo.setTitle(DIDWizardField.EXTENSION_TO.getDisplayTitle()); extensionTo.setWidth(50); extensionTo.setValidators(new RangeValidator()); manualEntry = new TextAreaItem(DIDWizardField.MANUAL_ENTRY.getName()); manualEntry.setTitle(DIDWizardField.MANUAL_ENTRY.getDisplayTitle()); manualEntry.setTitleVAlign(VerticalAlignment.TOP); manualEntry.setWidth(166); manualEntry.setValidators(new ManualValidator());
Code:
HandlerRegistration entryMethodReg = wizardForm.entryMethod.addChangedHandler(new ChangedHandler(){ @Override public void onChanged(ChangedEvent event) { if(event.getValue() != null && event.getValue().equals(EntryMethod.RANGE_ENTRY.toString())) { wizardForm.leftRangeEntryForm.setVisibility(Visibility.INHERIT); wizardForm.leftManualEntryForm.setVisibility(Visibility.HIDDEN); wizardForm.leftManualEntryForm.clearErrors(true); wizardForm.manualEntry.redraw(); } else { wizardForm.leftRangeEntryForm.setVisibility(Visibility.HIDDEN); wizardForm.leftManualEntryForm.setVisibility(Visibility.INHERIT); wizardForm.leftRangeEntryForm.clearErrors(true); wizardForm.country.redraw(); wizardForm.npa.redraw(); wizardForm.nxx.redraw(); wizardForm.extensionFrom.redraw(); wizardForm.extensionTo.redraw(); } } });
Code:
public class WindowedDIDWizardView extends Window implements View { protected WindowedDIDWizardController controller; protected DIDSelectorView target; protected DataSource dataSource; protected DataSource countryDS; protected DataSource carrierDS; protected DataSource didPortStatusDS; protected DataSource accountDS; protected DataSource csaDS; protected DIDWizardForm wizardForm; public WindowedDIDWizardView(HandlerManager eventBus, DIDSelectorView target) { super(); this.target = target; dataSource = DataSource.get("didWizard"); countryDS = DataSource.get("country"); carrierDS = DataSource.get("carrier"); didPortStatusDS = DataSource.get("didPortStatus"); accountDS = DataSource.get("account"); csaDS = DataSource.get("csa"); /* Create the controller */ controller = new WindowedDIDWizardController(eventBus); this.setAutoSize(true); this.setShowEdges(false); this.setStyleName("didWindow"); this.setHeaderStyle("didWindowHeader"); this.setShowShadow(true); this.setShadowDepth(10); this.setVisibility(Visibility.HIDDEN); this.setCanDragReposition(false); this.setCanDragResize(false); this.setTitle("Add DIDs"); this.setHeaderControls(HeaderControls.HEADER_LABEL, HeaderControls.CLOSE_BUTTON); wizardForm = new DIDWizardForm(); this.addItem(wizardForm); } @Override public void bind() { controller.bind(); } @Override public void init() { controller.init(); } @Override public void unbind() { controller.unbind(); } @Override public void destroy() { controller.destroy(); super.destroy(); } public class DIDWizardForm extends VStack { protected HStack formLayout; protected VStack notesLayout; protected DynamicForm entryMethodForm; protected DynamicForm leftRangeEntryForm; protected DynamicForm leftManualEntryForm; protected DynamicForm rightForm; protected DynamicForm buttonForm; protected ValuesManager vm; protected RadioGroupItem entryMethod; protected ComboBoxItem country; protected TextItem npa; protected TextItem nxx; protected TextItem extensionFrom; protected TextItem extensionTo; protected TextAreaItem manualEntry; protected ComboBoxItem carrier; protected ComboBoxItem portStatus; protected ComboBoxItem account; protected ComboBoxItem csa; protected RichTextEditor notes; protected ButtonItem createButton; protected ButtonItem resetButton; public DIDWizardForm() { super(); super.setAlign(Alignment.CENTER); this.setWidth(1050); formLayout= new HStack(); formLayout.setPadding(10); formLayout.setMembersMargin(5); notesLayout = new VStack(); entryMethodForm = new DynamicForm(); leftRangeEntryForm = new DynamicForm(); leftManualEntryForm = new DynamicForm(); rightForm = new DynamicForm(); buttonForm =new DynamicForm(); vm = new DIDWizardValuesManager(); vm.setDataSource(dataSource); vm.setSaveOperationType(DSOperationType.ADD); entryMethodForm.setDataSource(dataSource); leftRangeEntryForm.setDataSource(dataSource); leftManualEntryForm.setDataSource(dataSource); rightForm.setDataSource(dataSource); entryMethodForm.setValuesManager(vm); leftRangeEntryForm.setValuesManager(vm); leftManualEntryForm.setValuesManager(vm); rightForm.setValuesManager(vm); entryMethodForm.setStyleName("entryMethodForm"); entryMethodForm.setNumCols(4); leftRangeEntryForm.setNumCols(4); leftManualEntryForm.setVisibility(Visibility.HIDDEN); buttonForm.setColWidths(500, 500); buttonForm.setFixedColWidths(true); entryMethod = new RadioGroupItem(DIDWizardField.ENTRY_METHOD.getName()); entryMethod.setTitle(DIDWizardField.ENTRY_METHOD.getDisplayTitle()); entryMethod.setValueMap(EntryMethod.getValueMap()); entryMethod.setVertical(false); entryMethod.setWrap(false); entryMethod.setDefaultValue(EntryMethod.RANGE_ENTRY.toString()); country=new ComboBoxItem(DIDWizardField.COUNTRY_ID.getName()); country.setTitle(DIDWizardField.COUNTRY_ID.getDisplayTitle()); country.setColSpan(4); country.setOptionDataSource(countryDS); country.setValueField(CountryField.COUNTRY_ID.getName()); country.setDisplayField(CountryField.COUNTRY_NAME.getName()); country.setOptionOperationId("filtered"); country.setAutoFetchData(true); country.setValidators(new RangeValidator()); ListGridField countryFlag = new ListGridField(CountryField.COUNTRY_CODE.getName(), "Flag", 30); countryFlag.setType(ListGridFieldType.IMAGE); countryFlag.setImageURLPrefix("flags/16/"); countryFlag.setImageURLSuffix(".png"); ListGridField countryName = new ListGridField(CountryField.COUNTRY_NAME.getName(), CountryField.COUNTRY_NAME.getDisplayTitle()); country.setPickListFields(countryFlag, countryName); npa = new TextItem(DIDWizardField.NPA.getName()); npa.setTitle(DIDWizardField.NPA.getDisplayTitle()); npa.setWidth(50); npa.setValidators(new RangeValidator()); nxx = new TextItem(DIDWizardField.NXX.getName()); nxx.setTitle(DIDWizardField.NXX.getDisplayTitle()); nxx.setWidth(50); nxx.setValidators(new RangeValidator()); extensionFrom = new TextItem(DIDWizardField.EXTENSION_FROM.getName()); extensionFrom.setTitle(DIDWizardField.EXTENSION_FROM.getDisplayTitle()); extensionFrom.setWidth(50); extensionFrom.setValidators(new RangeValidator()); extensionTo = new TextItem(DIDWizardField.EXTENSION_TO.getName()); extensionTo.setTitle(DIDWizardField.EXTENSION_TO.getDisplayTitle()); extensionTo.setWidth(50); extensionTo.setValidators(new RangeValidator()); manualEntry = new TextAreaItem(DIDWizardField.MANUAL_ENTRY.getName()); manualEntry.setTitle(DIDWizardField.MANUAL_ENTRY.getDisplayTitle()); manualEntry.setTitleVAlign(VerticalAlignment.TOP); manualEntry.setWidth(166); manualEntry.setValidators(new ManualValidator()); carrier = new ComboBoxItem(DIDWizardField.CARRIER.getName()); carrier.setTitle(DIDWizardField.CARRIER.getDisplayTitle()); carrier.setOptionDataSource(carrierDS); carrier.setValueField(CarrierField.PROVIDER_ID.getName()); carrier.setDisplayField(CarrierField.PROVIDER_NAME.getName()); portStatus = new ComboBoxItem(DIDWizardField.PORT_STATUS.getName()); portStatus.setTitle(DIDWizardField.PORT_STATUS.getDisplayTitle()); portStatus.setOptionDataSource(didPortStatusDS); account = new ComboBoxItem(DIDWizardField.ACCOUNT.getName()); account.setTitle(DIDWizardField.ACCOUNT.getDisplayTitle()); account.setOptionDataSource(accountDS); account.setValueField(AccountField.ACCOUNT_ID.getName()); account.setDisplayField(AccountField.ACCOUNT_NAME.getName()); csa= new ComboBoxItem(DIDWizardField.CSA.getName()); csa.setTitle(DIDWizardField.CSA.getDisplayTitle()); csa.setOptionDataSource(csaDS); csa.setValueField(CSAField.CSA_ID.getName()); csa.setDisplayField(CSAField.CSA.getName()); notes = new RichTextEditor(); notes.setHeight(125); notes.setShowEdges(true); notes.setWidth("550"); notes.setOverflow(Overflow.HIDDEN); createButton = new ButtonItem("Create"); createButton.setEndRow(false); createButton.setAlign(Alignment.RIGHT); resetButton = new ButtonItem("Reset"); resetButton.setStartRow(false); entryMethodForm.setFields(entryMethod); leftRangeEntryForm.setFields(country, npa, nxx, extensionFrom, extensionTo); leftManualEntryForm.setFields(manualEntry); rightForm.setFields(carrier,portStatus,account, csa); DIDSearchFormDecorator.decorate(entryMethodForm, leftRangeEntryForm, leftManualEntryForm, rightForm); DIDSearchFormDecorator.decorate(entryMethod, country, npa, nxx, extensionFrom, extensionTo, manualEntry, carrier, portStatus, account, csa); Label notesLabel = new Label(); notesLabel.setContents(DIDWizardField.NOTES.getDisplayTitle()); notesLabel.setHeight("10"); notesLayout.addMember(notesLabel); notesLayout.addMember(notes); formLayout.addMember(leftRangeEntryForm); formLayout.addMember(leftManualEntryForm); formLayout.addMember(rightForm); formLayout.addMember(notesLayout); buttonForm.setFields(createButton, resetButton); this.addMember(entryMethodForm); this.addMember(formLayout); this.addMember(buttonForm); } } public class DIDWizardResult extends VStack { protected Label addedLabel; protected Label existingLabel; protected Label errorLabel; protected SelfLoadingShortDIDListGrid addedDIDList; protected SelfLoadingShortDIDListGrid existingDIDList; protected StringListGrid errorList; public DIDWizardResult(int[] addedDIDs, int[] existingDIDs, String[] errors) { super(); this.setWidth(1050); this.setPadding(10); if(addedDIDs.length > 0) { addedLabel = new Label(); addedLabel.setContents("Added DIDs"); addedLabel.setStyleName("sectionTitle"); addedLabel.setHeight(14); addedDIDList = new SelfLoadingShortDIDListGrid(); this.addMember(addedLabel); this.addMember(addedDIDList); addedDIDList.setDIDIds(addedDIDs); } if(existingDIDs.length > 0) { existingLabel = new Label(); existingLabel.setContents("Existing DIDs"); existingLabel.setStyleName("sectionTitle"); existingLabel.setHeight(14); existingDIDList = new SelfLoadingShortDIDListGrid(); this.addMember(existingLabel); this.addMember(existingDIDList); existingDIDList.setDIDIds(existingDIDs); } if(errors.length > 0) { errorLabel = new Label(); errorLabel.setContents("The following DIDs generated errors:"); errorLabel.setStyleName("sectionTitle"); errorLabel.setHeight(14); errorList = new StringListGrid(); this.addMember(errorLabel); this.addMember(errorList); errorList.setStringArray(errors); } } } public class DIDWizardValuesManager extends ValuesManager { @Override public void saveData() { this.setValue(DIDWizardField.NOTES.getName(), wizardForm.notes.getValue()); super.saveData(); } } public class WindowedDIDWizardController extends AbstractController { public WindowedDIDWizardController(HandlerManager eventBus) { super(eventBus); } public void bind() { /* Add HasChangedHandler for entryMethod */ HandlerRegistration entryMethodReg = wizardForm.entryMethod.addChangedHandler(new ChangedHandler(){ @Override public void onChanged(ChangedEvent event) { if(event.getValue() != null && event.getValue().equals(EntryMethod.RANGE_ENTRY.toString())) { wizardForm.leftRangeEntryForm.setVisibility(Visibility.INHERIT); wizardForm.leftManualEntryForm.setVisibility(Visibility.HIDDEN); wizardForm.leftManualEntryForm.clearErrors(true); wizardForm.manualEntry.redraw(); } else { wizardForm.leftRangeEntryForm.setVisibility(Visibility.HIDDEN); wizardForm.leftManualEntryForm.setVisibility(Visibility.INHERIT); wizardForm.leftRangeEntryForm.clearErrors(true); wizardForm.country.redraw(); wizardForm.npa.redraw(); wizardForm.nxx.redraw(); wizardForm.extensionFrom.redraw(); wizardForm.extensionTo.redraw(); } } }); /* Add binding for create button */ HandlerRegistration createButtonReg = wizardForm.createButton.addClickHandler(new ClickHandler(){ @Override public void onClick(ClickEvent event) { wizardForm.vm.saveData(new DIDWizardCallback()); } }); this.addHandlerRegistration(entryMethodReg); } } public class RangeValidator extends RequiredIfValidator { public RangeValidator() { super(); this.setExpression(new RequiredIfFunction(){ @Override public boolean execute(FormItem formItem, Object value) { if(wizardForm.entryMethod.getValue().equals(EntryMethod.RANGE_ENTRY.toString())) { return true; } else { return false; } } }); } } public class ManualValidator extends RequiredIfValidator { public ManualValidator() { super(); this.setExpression(new RequiredIfFunction(){ @Override public boolean execute(FormItem formItem, Object value) { if(wizardForm.entryMethod.getValue().equals(EntryMethod.MANUAL.toString())) { return true; } else { return false; } } }); } } public class DIDWizardCallback implements DSCallback { @Override public void execute(DSResponse response, Object rawData, DSRequest request) { Log.debug("Call back executed."); Record[] results = response.getData(); Log.debug("Results contains " + results.length +" records."); for(Record result : results) { String[] attribs = result.getAttributes(); for(String attrib : attribs) { Log.debug(attrib + ": " + result.getAttribute(attrib)); } } Record result = results[0]; int[] allDIDs = result.getAttributeAsIntArray(DIDWizardField.FULL_DID_LIST.getName()); int[] addedDIDs= result.getAttributeAsIntArray(DIDWizardField.ADDED_DID_LIST.getName()); int[] existingDIDs = result.getAttributeAsIntArray(DIDWizardField.EXISTING_DID_LIST.getName()); String[] errors = result.getAttributeAsStringArray(DIDWizardField.ERROR_LIST.getName()); target.addDIDIds(allDIDs); DIDWizardResult wizardResult = new DIDWizardResult(addedDIDs, existingDIDs, errors); WindowedDIDWizardView.this.removeItem(wizardForm); WindowedDIDWizardView.this.addItem(wizardResult); } } }
Comment