Textbox should accept only numbers, I would like to use anyother Handlers other than ChangedHandler/ Changehandler/ KeyPressHandler
My Validation class,
public class UnderLyingIDChangeHandler implements ChangedHandler {
private final CreditRiskView creditRiskView;
public UnderLyingIDChangeHandler(CreditRiskView creditRiskView) {
this.creditRiskView = creditRiskView;
}
#Override
public void onChanged(ChangedEvent event) {
String value= (String) event.getItem().getValue();
if(!value.matches("[0-9]*")){
creditRiskView.invalidUnderlyingID();
}
}
This is the main class where I need to show the validation
public class CreditRiskView{
private TextItem underlyingIDField;
public void addunderlyingIDInputChangeHadler(ChangedHandler changedHandler) {
//logic is that this method will invoked in the UnderLyingIDChangeHandler class
underlyingIDField.addChangedHandler(changedHandler);
}
public void invalidUnderlyingID(){
// I don't know how to set an error message as underlyingIDField.clearValue()
method is not doing well.
}
}
If the textbox is a TextItem in a DynamicForm it works like this:
IsIntegerValidator isIntegerValidator = new IsIntegerValidator();
isIntegerValidator.setErrorMessage("error message");
textItem.setValidators(isIntegerValidator);
And to show the errors like that when you call the form.validate() you need to set the setShowInlineErrors(true) in the form.
What about limiting characters that can be entered by the user?
Please see this sample:
http://www.smartclient.com/smartgwt/showcase/#form_keypress_filter
Related
In JavaFX I want to check if a checkbox is selected and I want to do this using the lookup(#id) method. However this method returns a Node, which doesn't have the isSelected() method.
The code below shows the GUIController and a class Visualize it calls, where the status of the checkbox is read. I added a solution (reading the checkbox properties in GUIController and passing them to Visualize), but this is not how I want to proceed. I whish that the checkbox status is read in Visualize, because there will be many other GUI elements that I need to read so it is more compact to pass on a single object to Visualize instead of a list precomputed in GUIController.
Thank you for suggestions!
GUI Controller:
public class GUIController implements Initializable {
#FXML private AnchorPane RootPane;
#FXML private CheckBox TextCheckBox;
#Override
public void initialize(URL url, ResourceBundle rb) {
Boolean TextCheckBoxSelected = TextCheckBox.isSelected();
Visualize visualizeInstance = new Visualize();
root3D = visualizeInstance.draw(RootPane, TextCheckBoxSelected);
/* ... */
Class called by GUIController:
public class Visualize {
public Visualize() {
//
}
public Group draw(AnchorPane RootPane, Boolean TextCheckBoxSelected) {
System.out.println(RootPane.lookup("#TextCheckBox"));
System.out.println(TextCheckBoxSelected);
/* ... */
Output:
CheckBox[id=TextCheckBox, styleClass=check-box]'Text'
true
If you really want to do it this way, just downcast the result of the lookup:
public class Visualize {
// ...
public Group draw(AnchorPane rootPane) {
CheckBox textCheckBox = (CheckBox) rootPane.lookup("#TextCheckBox");
boolean selected = textCheckBox.isSelected();
// ...
}
}
If you are doing this because you need your Visualize object to respond to changes in the CheckBox's selected state, then consider passing a BooleanProperty instead, which you can observe if you need:
public class Visualize {
private BooleanProperty selectedProperty ;
public Visualize(BooleanProperty selectedProperty) {
this.selectedProperty = selectedProperty ;
// ...
}
// ...
public Group draw() {
boolean selected = selectedProperty.get();
// ...
}
}
and
Visualize visualizeInstance = new Visualize(textCheckBox.selectedProperty());
root3D = visualizeInstance.draw();
Spring MVC support request parameter to javabean. But when I want to bind boolean,
It is still not work in javabean.
If the code in controller is:
public void test(#RequestParam(value="isCheck") boolean isCheck)
I can get the isCheck boolean value.
But when the code in contoller is:
public void test(TestVO testVO)
TestVO javabean:
public class TestVO {
private boolean isPrecheck;
public boolean isPrecheck() {
return isPrecheck;
}
public void setPrecheck(boolean isPrecheck) {
this.isPrecheck = isPrecheck;
}
}
I can not set the request parameter to this Javabean.
Anyone has ideas?
You can you the PropertiesEditor of the Spring.
http://static.springsource.org/spring/docs/3.2.x/javadoc-api/org/springframework/beans/propertyeditors/CustomBooleanEditor.html
Inside your controller create a method to set the editor
public void initBinder(WebDataBinder binder) {
binder.registerCustomEditor(Boolean.class, new CustomBooleanEditor(allowEmpty???));
}
This is due to boolean naming convention and associated ambiguity with its getter methods.
Rename your boolean from isPrecheck to precheck and it will work.
I have a Page which consist of AddPage.xaml and AddPage.xaml.cs. I want to create a generic class AddPage which extends from PhoneApplicationPage to outsource some repetitive code like Save or Cancel.
If I change the base class from PhoneApplicationPage to my new generic class, I get this error: Partial declarations of 'AddPage' must not specify different base classes.
To accomplish this you need to do the following.
First, create your base class
public class SaveCancelPhoneApplicationPage : PhoneApplicationPage
{
protected void Save() { ... }
protected void Cancel() { ... }
}
Then, your AddPage needs to be modified to inherit from the base class. The main places this is needed is within the code (AddPage.xaml.cs) AND within the xaml
Code:
public partial class AddPage : SaveCancelPhoneApplicationPage { ... }
Xaml:
<local:SaveCancelPhoneApplicationPage
x:Class="MyPhone.Namespace.AddPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyPhone.Namespace"
<!-- other xaml elements -->
</local:SaveCancelPhoneApplicationPage>
UPDATE: Info added based on comments
If you need to have generic like functionality and you must use the Page to do this (rather than a ViewModel) then you can still do this using generic methods
public abstract class SaveCancelPhoneApplicationPage : PhoneApplicationPage
{
protected override void OnNavigatedTo(blaa,blaa)
{
var obj = CreateMyObject();
obj.DoStuff();
}
// You should know what your objects are,
// don't make it usable by every phone dev out there
protected MyBaseObject MyObject { get; set; }
protected T GetMyObject<T>() where T : MyBaseObject
{
return MyObject as T;
}
}
public class AddPage : SaveCancelPhoneApplicationPage
{
public AddPage()
{
MyObject = new MyAddObject();
}
}
In order to outsource some functions you just declare some add class which does the common work. Having another page doesn't do that work.
public class Add
{
public bool SaveContent(string filename, string content)
{
....//some content
return true;
}
public string ViewContent(string filename)
{
string content="";
.....
return content;
}
}
Add this part of code where you thought it is redundant.
Add obj=new Add();
obj.SaveContent("myfile.txt","Hello.This is my content.");
string content("myfile.txt");
Tell me if this is what you intend or not.
I'm adding a user validator using the initBinder method:
#InitBinder
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new UserValidator());
}
Here is the UserValidator
public class UserValidator implements Validator {
public boolean supports(Class clazz) {
return User.class.equals(clazz);
}
public void validate(Object target, Errors errors) {
User u = (User) target;
// more code here
}
}
The validate method is getting properly called during the controller method call.
#RequestMapping(value = "/makePayment", method = RequestMethod.POST)
public String saveUserInformation(#Valid User user, BindingResult result, Model model){
// saving User here
// Preparing CustomerPayment object for the payment page.
CustomerPayment customerPayment = new CustomerPayment();
customerPayment.setPackageTb(packageTb);
model.addAttribute(customerPayment);
logger.debug("Redirecting to Payment page.");
return "registration/payment";
}
But while returning to the payment screen I'm getting this error:
java.lang.IllegalStateException: Invalid target for Validator [com.validator.UserValidator#710db357]: com.domain.CustomerPayment[ customerPaymentId=null ]
org.springframework.validation.DataBinder.setValidator(DataBinder.java:476)
com.web.UserRegistrationController.initBinder(UserRegistrationController.java:43)
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)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.initBinder(HandlerMethodInvoker.java:393)
org.springframework.web.bind.annotation.support.HandlerMethodInvoker.updateModelAttributes(HandlerMethodInvoker.java:222)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:429)
org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:414)
This might be because I'm returning a CustomerPayment and there is not validator defined for that.
I'm also not able to add multiple validators in initBinder method.
How can I fix this?
You need to set the value of the #InitBinder annotation to the name of the command you want it to validate. This tells Spring what to apply the binder to; without it, Spring will try to apply it to everything. This is why you're seeing that exception: Spring is trying to apply the binder - with your UserValidator - to a parameter of type CustomerPayment.
In your specific case, it looks like you need something like:
#InitBinder("user")
protected void initBinder(WebDataBinder binder) {
binder.setValidator(new UserValidator());
}
To your second question, as Rigg802 explained, Spring does not support attaching multiple validators to a single command. You can, however, define multiple #InitBinder methods for different commands. So, for example, you could put the following in a single controller and validate your user and payment parameters:
#InitBinder("user")
protected void initUserBinder(WebDataBinder binder) {
binder.setValidator(new UserValidator());
}
#InitBinder("customerPayment")
protected void initPaymentBinder(WebDataBinder binder) {
binder.setValidator(new CustomerPaymentValidator());
}
It's a bit tricky to do, 1 controller has only 1 validator on 1 command object.
you need to create a "Composite Validator" that will get all the validators and run them seperately.
Here is a tutorial that explains how to do it: using multiple validators
You can add multiple validators by iterating over all org.springframework.validation.Validator in an ApplicationContext and set up suitable ones in #InitBinder for each request.
#InitBinder
public void setUpValidators(WebDataBinder webDataBinder) {
for (Validator validator : validators) {
if (validator.supports(webDataBinder.getTarget().getClass())
&& !validator.getClass().getName().contains("org.springframework"))
webDataBinder.addValidators(validator);
}
}
See my project for examples and simple benchmarks. https://github.com/LyashenkoGS/spring-mvc-and-jms-validation-POC/tree/benchamark
I do not see a reason why Spring does not filter out all validators which are not applicable to the current entity by default which forces to use things like CompoundValidator described by #Rigg802.
InitBinder allows you to specify name only which give you some control but not full control over how and when to apply your custom validator. Which from my perspective is not enough.
Another thing you can do is to perform check yourself and add validator to binder only if it is actually necessary, since binder itself has binding context information.
For example if you want to add a new validator which will work with your User object in addition to built-in validators you can write something like this:
#InitBinder
protected void initBinder(WebDataBinder binder) {
Optional.ofNullable(binder.getTarget())
.filter((notNullBinder) -> User.class.equals(notNullBinder.getClass()))
.ifPresent(o -> binder.addValidators(new UserValidator()));
}
There is a simple hack, always return true in supports method, and delegate the class checking to validate. Then basically you can add multiple validator in the initBinder without issue.
#Component
public class MerchantRegisterValidator implements Validator {
#Autowired
private MerchantUserService merchantUserService;
#Autowired
private MerchantCompanyService merchantCompanyService;
#Override
public boolean supports(Class<?> clazz) {
return true; // always true
}
#Override
public void validate(Object target, Errors errors) {
if (!RegisterForm.getClass().equals(target.getClass()))
return; // do checking here.
RegisterForm registerForm = (RegisterForm) target;
MerchantUser merchantUser = merchantUserService.getUserByEmail(registerForm.getUserEmail());
if (merchantUser != null) {
errors.reject("xxx");
}
MerchantCompany merchantCompany = merchantCompanyService.getByRegno(registerForm.getRegno());
if (merchantCompany != null) {
errors.reject("xxx");
}
}
}
Multiple validator on one command is supported with Spring MVC 4.x now. You could use this snippet code:
#InitBinder
protected void initBinder(WebDataBinder binder) {
binder.addValidators(new UserValidator(), new CustomerPaymentValidator());
}
The safest way is to add a generic validator handling that Controller:
#InitBinder
public void initBinder(WebDataBinder binder) {
binder.setValidator(new GenericControllerOneValidator());
}
Then, in the generic validator you can support multiple request body models and based of the instance of the object, you can invoke the appropriate validator:
public class GenericValidator implements Validator {
#Override
public boolean supports(Class<?> aClass) {
return ModelRequestOne.class.equals(aClass)
|| ModelRequestTwo.class.equals(aClass);
}
#Override
public void validate(Object body, Errors errors) {
if (body instanceof ModelRequestOne) {
ValidationUtils.invokeValidator(new ModelRequestOneValidator(), body, errors);
}
if (body instanceof ModelRequestTwo) {
ValidationUtils.invokeValidator(new ModelRequestTwoValidator(), body, errors);
}
}
}
Then you add your custom validations inside for each model validator implementatios. ModeRequestOneValidator and ModeRequestTwoValidator still need to implement the Validator interface of org.springframework.validation
Also, do not forget to use #Valid ModeRequestOne and #Valid ModeRequestTwo inside the controllers method call.
One addition to Annabelle's answer:
If controller has this method parameter and you want to validate that one specifically
#RequestMapping(value = "/users", method = RequestMethod.POST)
public String findUsers(UserRequest request){..}
Then the binding should be lower case of the class name (but just the first letter, and not everything else)
#InitBinder("userRequest")
protected void initUserBinder(WebDataBinder binder) {
binder.setValidator(new YourValidator());
}
Declare request as
(... , Model model,HttpServletRequest request)
and change
model.addAttribute(customerPayment);
to
request.setAttribute("customerPayment",customerPayment);
New to the world of TDD and I have soon find out that mocking at times is not as easy.
We are using MOQ at work so I need to learn how to do this using moq
I have some code using the command pattern and works a treat.However If were to test drive it I would not know how to do it implementing the code below.
I have done the following
Created BaseToolStripMenuItem:ToolStripMenuItem and added a Command Property (see below)
Created a windows form and added a menuStrip with 2 item Open and Exit
In the form I just add to map the command to a button and all works a treat.
I would like to change the code so that I can UnitTest using Moq but cannot see how???
Can you help?
Any suggestions?
Thanks a lot!!
public interface ICommand
{
void Execute()
}
public abstract class BaseCmd :ICommand
{
protected ProcessMenuCommand ProcessCommand;
protected MenuCommandFactory Factory;
protected BaseCmd(ProcessMenuCommand processMenuCommand, MenuCommandFactory cmdfactory)
{
ProcessCommand = processMenuCommand;
Factory = cmdfactory;
}
abstract public void Execute();
}
public class BaseToolStripMenuItem : ToolStripMenuItem
{
public BaseToolStripMenuItem()
{
Click += MenuItemClick;
Command = null;
}
public BaseCmd Command { get; set; }
private void MenuItemClick(object sender, EventArgs args)
{
if (Command != null) Command.Execute();
}
}
public class MenuCommandFactory
{
private readonly ProcessMenuCommand _processMenuCommand;
public MenuCommandFactory(ProcessMenuCommand processMenuCommand)
{
_processMenuCommand = processMenuCommand;
}
public OpenFileCmd OpenFile()
{
return new OpenFileCmd(_processMenuCommand,this);
}
public ExitCmd Exit()
{
return new ExitCmd(_processMenuCommand, this);
}
}
public class OpenFileCmd:BaseCmd
{
public OpenFileCmd(ProcessMenuCommand processMenu,MenuCommandFactory menuCommandFactory)
:base(processMenu,menuCommandFactory)
{
}
public override void Execute()
{
ProcessCommand.OpenFile();
}
}
public class ProcessMenuCommand
{
public void OpenFile()
{
MessageBox.Show("Open a file");
}
public void Exit()
{
MessageBox.Show("Exiting");
}
}
public class ExitCmd:BaseCmd
{
public ExitCmd(ProcessMenuCommand processMenu, MenuCommandFactory menuCommandFactory)
:base(processMenu,menuCommandFactory)
{
}
public override void Execute()
{
ProcessCommand.Exit();
}
}
//In the form
public partial class Form1 : Form
{
private ProcessMenuCommand menuCommandProcessor;
private MenuCommandFactory factory;
public Form1()
{
InitializeComponent();
// Created editor and factory.
menuCommandProcessor = new ProcessMenuCommand();
factory = new MenuCommandFactory(menuCommandProcessor);
// Get concrete command objects from factory and assign to corresponding menu items and tool strip buttons.
tsOpen.Command = factory.OpenFile();
tsExit.Command = factory.Exit();
}
}
However If were to test drive it I would not know how to do it implementing the code below
The idea about TDD is that it drives you towards an implementation. There are many implementations you could never arrive at using TDD, so your question doesn't really make much sense.
Try to write some tests that drive you towards your goal without having a preconceived image of the solution at which you wish to arrive. It will often turn out that you end up at an entirely different (and better) place than what you originally thought.
A simple Novice Rule: no abstract classes. Try designing again with only interfaces and concrete classes. You'll notice it's easier to test-drive the result.
As for "how to TDD a Command object", a Command is just a class that provides a single action. Test-drive it the same way you would test-drive any method, except you name the method Execute().