I'm currently using three different forms, RadioChoice, DateField and DropDownChoice, in an application where the page reacts based on what the user picks from this form. The problem here is that when I submit the form that is using DateField and DropDownChoice, it does an refresh of the page and the choice from the RadioChoice is remembered but the default choice is shown instead. So my question is if it's either possible to clear the values and set them back to default after a refresh, or make the submit of DateField and DropDownChoice not refresh the page?
//RADIO CHOICE
RadioChoice<String> radioChoice = new RadioChoice<String>("radio", new PropertyModel<String>(this, "selectedRadio"),this.radioChoiceList);
radioChoice.add(new AjaxFormChoiceComponentUpdatingBehavior()
{
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
protected void onUpdate(AjaxRequestTarget target)
{
target.appendJavaScript(changeBaseLayerJS(Page.this.currentMap, Page.this.selectedRadio));
Page.this.currentMap = Page.this.selectedRadio;
}
});
Form<?> radioForm = new Form<Void>("radioForm");
add(radioForm);
radioForm.add(radioChoice);
//DATEFIELD AND DROPDOWNCHOICE
DateField fromDateField = new DateField("fromDateField", new PropertyModel<Date>(
this, "fromDate"));
DateField toDateField = new DateField("toDateField", new PropertyModel<Date>(
this, "toDate"));
DropDownChoice<String> idvNameMenu = new DropDownChoice<String>("idvNameMenu", new PropertyModel<String>(this, "idvTrackName"), individualChoiceList);
Form<?> trackingForm = new Form<Void>("trackingForm"){
/**
*
*/
private static final long serialVersionUID = 1L;
#Override
protected void onSubmit()
{
//do stuff
}
};
Normal (non-Ajax) form submit leads to full page repaint. Ajax form submit will repaint only the components you put into the AjaxRequestTarget.
You can use form.add(new AjaxFormSubmittingBehavior() {...}) to do it with Ajax.
Or you can zero-fy you model objects in onSubmit:
#Override
protected void onSubmit()
{
// do stuff
// save in database
fromDate = null; // or = new Date();
toDate = null;
idvTrackName = "some good default value";
}
Related
I have a form where their is a dropdown and checkbox . When i dont provide any input i receive the error message set through the Feedback Panel as below code
private Form<ReportCriteria> createCriteriaPanel(String id, IModel<ReportCriteria> model) {
SelectionForm form = new SelectionForm(id, model);
ReportCriteria criteria = (ReportCriteria) getDefaultModelObject();
.......
FeedbackPanel fb = new FeedbackPanel("feedback");
fb.setOutputMarkupId(true);
form.add(fb);
DropDownChoice<Project> billableProjectsList = new DropDownChoice<>(
"projectsList",
......
new ChoiceRenderer<Project>("fullNameWithCustomer"));
form.add(billableProjectsList);
CheckGroup<Project> unbillablePrjct = .......
form.add(new FormComponentValidator(billableProjectsList, unbillablePrjct));
form.getFeedbackMessages().clear();
}
protected void onSubmit() {
SelectionForm.this.getFeedbackMessages().size());
TimesheetExportCriteriaPanel.this.SelectionForm.findForm("criteriaForm").getFeedbackMessages();
}
all the feedbackmessages value is empty and not retreieving anything .
I receive the error message from FormValidator correctly when i dont provide any inputs . When i provide the inputs and submit , the form refreshes and loads with the same error message .
I want it to clear when we provide valid input .
When checked on forums , i found for Wicket 6.x we need to use component.getFeedbackMessages() , but it is empty for me .
I am new to wicket .
Please help with the inputs .
public class FormComponentValidator extends AbstractFormValidator {
private static final long serialVersionUID = 1L;
private FormComponent<?>[] components;
#SuppressWarnings("unchecked")
public FormComponentValidator(FormComponent<?> selectedBillableProject, FormComponent<?> selectedUnBillableProject) {
components = new FormComponent[]{selectedBillableProject, selectedUnBillableProject};
}
/*
* (non-Javadoc)
* #see org.apache.wicket.markup.html.form.validation.IFormValidator#getDependentFormComponents()
*/
public FormComponent<?>[] getDependentFormComponents() {
return components;
}
/*
* (non-Javadoc)
* #see org.apache.wicket.markup.html.form.validation.IFormValidator#validate(org.apache.wicket.markup.html.form.Form)
*/
public void validate(Form<?> form ) {
if ((org.apache.commons.lang.StringUtils.isEmpty(components[0].getInput()) || components[0].getInput() == null )
&& (org.apache.commons.lang.StringUtils.isEmpty(components[1].getInput()) || components[1].getInput() == null)) {
error(components[0], "project.Required");
}
}
}
private void configureFeedback() {
// activate feedback panel
final FeedbackPanel feedbackPanel = new FeedbackPanel("feedback");
feedbackPanel.setOutputMarkupId(true);
feedbackPanel.setVisible(false);
add(feedbackPanel);
// don't show filtered feedback errors in feedback panel
final int[] filteredErrorLevels = new int[] { FeedbackMessage.ERROR };
feedbackPanel.setFilter(new IFeedbackMessageFilter() {
#Override
public boolean accept(FeedbackMessage message) {
for (int errorLevel : filteredErrorLevels) {
if (message.getLevel() == errorLevel) {
return false;
}
}
return true;
}
When submitting a Form Wicket runs all configured validators on all FormComponents (like TextInput, TextArea, DropDownChoice, etc.). If there is a validation error then a FeedbackMessage is associated with its respective FormComponent.
When rendering a FeedbackPanel Wicket visits all FormComponents and renders their FeedbackMessages (errors, infos, etc.).
At the end of the request cycle Wicket removes all rendered FeedbackMessages. If a FeedbackMessage is not rendered by any IFeedback component (like FeedbackPanel) then it will stay for the next request cycle.
This is done by DefaultCleanupFeedbackMessageFilter.
Put a breakpoint at DefaultCleanupFeedbackMessageFilter#accept() and see whether the problematic message is being accepted or not.
I'm trying to mount an ImageResourceReference on my Page, but the ExternalLink is mounted multiple times (everytime I reload the page, I get a new additional link (same one).
For example when I start the server and load the page for the first time, there's just one ExternalLink, the second time, two links, third time three, etc...
What could be the reason for that?
Here is my code:
WebApp.java:
void init() {
.....
mountResource("/book/number/${number}/images/ray/${name}", new ImageResourceReference());
....
}
ImageResourcesPanel:
public class ImageResourcesPanel extends Panel {
private static final long serialVersionUID = -8723530004274531683L;
private static Logger logger = LoggerFactory.getLogger(ImageResourcesPanel.class
.getName());
/**
* The image names for which dynamic images will be generated
*/
private static List<String> IMAGE_NAMES = new ArrayList<String>();
public ImageResourcesPanel(final String wicketId, final IModel<Device> model) {
super(wicketId, model);
String pathToImage = "images";
IMAGE_NAMES.add(pathToImage);
ListView<String> listView = new ListView<String>("list", IMAGE_NAMES) {
private static final long serialVersionUID = 1L;
#Override
protected void populateItem(ListItem<String> item) {
logger.debug("Executed!");
ResourceReference imagesResourceReference = new ImageResourceReference();
PageParameters imageParameters = new PageParameters();
int number = model.getObject().getNumber();
String imageName = item.getModelObject();
String folder = model.getObject().getLinkToFolder();
imageParameters.set("name", imageName);
imageParameters.set("number", number);
imageParameters.set("folder", folder);
// generates nice looking url (the mounted one) to the current image
CharSequence urlForWordAsImage = getRequestCycle().urlFor(imagesResourceReference, imageParameters);
ExternalLink link = new ExternalLink("link", urlForWordAsImage.toString());
link.setBody(Model.of(imageName));
item.add(link);
}
};
add(listView);
}
}
Got it!
I just had to make the ListView empty after mounting the image on the page. I just added a line of code after adding the link to the ListView-Item:
`IMAGE_NAMES.remove(pathToImage);`
I am stuck with images. I need to upload an image and then display it on my page.
What I am doing now is uploading file like this:
private Picture picture; *// picture model*
private FileUploadField fileUpload;
public PictureUploader() {
Form<?> form = new Form<Void>("uploadForm") {
/**
*
*/
private static final long serialVersionUID = -694488846250739923L;
protected void onSubmit() {
FileUpload uploadedFile = fileUpload.getFileUpload();
File newFile = new File(uploadedFile.getClientFileName());
picture.setImage(newFile);
PageParameters pageParameter = new PageParameters();
pageParameter.put("file", picture.getImage());
setResponsePage(DataPage.class,pageParameter);
}
};
add(form);
form.setMultiPart(true);
form.add(setFileUpload(new FileUploadField("fileUpload")));
}
Then I submit it and go to DataPage ( I show only the constructor):
public DataPage(final PageParameters parameters) {
File file;
if (parameters.containsKey("file")) {
// WHAT TO DO HERE? SINCE GET() FROM PAGEPARAMETERS DOES NOT WORK FOR IT!
}
final Label result = new Label("result", ?????);
add(result);
}
Who knows how to make it, please, help me figure it out.
Is it possible to nest forms in Wicket that are independent of each other? I want to have a form with a submit button and a cancel button. Both buttons should direct the user to the same page (let's call it Foo). The submit button should send some info to the server first; the cancel button should do nothing.
Here's a really simplified version of my existing code:
Form form = new Form() {
public void onSubmit()
{
PageParameters params = new PageParameters();
params.put("DocumentID", docID);
setResponsePage(Foo.class, params);
}
};
DropDownChoice<String> ddc = new DropDownChoice<String>("name", new PropertyModel<String>(this, "nameSelection"), names);
ddc.setRequired(true);
final Button submitButton = new Button("Submit") {
public void onSubmit() { doSubmitStuff(true); }
};
final Button cancelButton = new Button("Cancel") {
public void onSubmit() { doSubmitStuff(false); }
};
form.add(ddc);
form.add(submitButton);
form.add(cancelButton);
form.add(new FeedbackPanel("validationMessages"));
The problem is, I just added a validator, and it fires even if I press the cancel button, since the cancel button is attached to the same form as everything else. This could be avoided if the cancel button were in a separate form. As far as I know, I can't create a separate form because — due to the structure of the HTML — the separate form would be under the existing form in the component hierarchy.
Can I make the forms separate somehow in spite of the hierarchy? Or is there some other solution I can use?
EDIT:
In response to Don Roby's comment, this is a bit closer to what my code looked like back when I was trying setDefaultFormProcessing():
Form<Object> theForm = new Form<Object>("theForm") {
public void onSubmit()
{
PageParameters params = new PageParameters();
params.put("DocumentID", docID);
setResponsePage(Foo.class, params);
}
};
final CheckBox checkbox = new CheckBox("checkbox", new PropertyModel<Boolean>(this, "something"));
checkbox.add(new PermissionsValidator());
theForm.add(checkbox);
final Button saveButton = new Button("Save") {
public void onSubmit()
{ someMethod(true); }
};
final Button cancelButton = new Button("Cancel") {
public void onSubmit()
{ someMethod(false); }
};
cancelButton.setDefaultFormProcessing(false);
theForm.add(saveButton);
theForm.add(cancelButton);
theForm.add(new FeedbackPanel("validationMessages"));
There is an even simpler solution: call the setDefaultFormProcessing method on the cancel button with false as a parameter:
cancelButton.setDefaultFormProcessing(false);
This way, clicking the cancel button will bypass the form validation (and model updating), directly calling the onSubmit function.
It is possible to "nest" forms in wicket.
See this wiki entry
for some notes on how it works and this wiki entry for how it interacts with validation.
But for what you're after, the answer from Jawher should have worked and is much simpler.
Look at this example code for hints on getting that working.
I'm wondering if you've simplified your code too far in this posting. Can you produce a sample small enough to post that definitely has the problem?
I have a Page with a Wizard component. The user can navigate the panels of the wizard by using the next and previous buttons which I have performing full (non-ajax) form submissions so that the app is back-button friendly.
When the next button is clicked, I would like to attempt ajax form validation (if javascript is enabled). I tried doing:
nextButton.add( new AjaxFormValidatingBehavior( form, "onsubmit") );
to add such validation. The behaviour works - however, when validation errors occur the browser still submits the entire form.
What is the Wicket way to prevent the browser from submitting the form in this case?
Override the onError() method on either the form or the AjaxFormValidatingBehavior. If you do it on the behavior, I am not sure if that will prevent the form from submitting or not.
new AjaxFormValidatingBehavior( form, "onsubmit") {
public void onSubmit() {}
public void onError() {}
}
Maybe a bit to late but here is the answer:
public class SomePage extends WebPage {
private FeedbackPanel feedbackMessageError = new FeedbackPanel("feedbackTabAddEmpMesError", new ExactLevelFeedbackMessageFilter(FeedbackMessage.ERROR));
public SomePage(String id) {
final Form<Void> form = new Form<>("tabFormAddEmp");
add(form);
//Name textfield cannot be empty
final FormComponent<String> tabAddEmpName = new RequiredTextField<>("tabAddEmpName", Model.of(""));
tabAddEmpName.setLabel(Model.of("Name"));
tabAddEmpName.setOutputMarkupId(true);
//Salarynumber has to be minimal 10 char long
final FormComponent<String> tabAddEmpLoon = new RequiredTextField<>("tabAddEmpLoon", Model.of(""));
tabAddEmpLoon.add(new StringValidator(10, null)).setLabel(Model.of("Salarynumber"));
tabAddEmpLoon.setOutputMarkupId(true);
final Button button = new Button("tabFormAddEmpBut");
form.add(tabAddEmpName , tabAddEmpLoon, button);
button.add(new AjaxFormValidatingBehavior(form, "onclick") {
#Override
public void onError(AjaxRequestTarget target) {
//Add feedbackpanel to your html and voila!
target.add(feedbackMessageError);
}
#Override
protected void onSubmit(AjaxRequestTarget target) {
//Do some logic over here
}
}
}
}