In a Wicket Panel i implemented a method called showAttentiePopup(AjaxRequestTarget) which shows an ModalWindow popup screen. This method works fine when i call it from the same Panel. But when I try to call the method from another Panel it crashes with the following error:
java.lang.IllegalStateException: No Page found for component [MarkupContainer [Component id = createAttentie]]
at org.apache.wicket.Component.getPage(Component.java:1665)
at org.apache.wicket.RequestCycle.urlFor(RequestCycle.java:851)
at org.apache.wicket.Component.urlFor(Component.java:3170)
at org.apache.wicket.behavior.AbstractAjaxBehavior.getCallbackUrl(AbstractAjaxBehavior.java:123)
at org.apache.wicket.ajax.AbstractDefaultAjaxBehavior.getCallbackScript(AbstractDefaultAjaxBehavior.java:116)
at org.apache.wicket.ajax.AbstractDefaultAjaxBehavior.getCallbackScript(AbstractDefaultAjaxBehavior.java:104)
at org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow$CloseButtonBehavior.getCallbackScript(ModalWindow.java:876)
at org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow.getWindowOpenJavascript(ModalWindow.java:1005)
at org.apache.wicket.extensions.ajax.markup.html.modal.ModalWindow.show(ModalWindow.java:286)
at nl.topicuszorg.fks.web.client.dossier.overzichten.documenten.AttentieOverzichtPanel.showAttentiePopup(AttentieOverzichtPanel.java:171)
at nl.topicuszorg.fks.web.client.dossier.overzichten.documenten.EditFileDocumentPanel$2.onSubmit(EditFileDocumentPanel.java:195)
at org.apache.wicket.ajax.markup.html.form.AjaxSubmitLink$1.onSubmit(AjaxSubmitLink.java:94)
at org.apache.wicket.ajax.form.AjaxFormSubmitBehavior.onEvent(AjaxFormSubmitBehavior.java:128)
at org.apache.wicket.ajax.AjaxEventBehavior.respond(AjaxEventBehavior.java:163)
at org.apache.wicket.ajax.AbstractDefaultAjaxBehavior.onRequest(AbstractDefaultAjaxBehavior.java:297)
Someone an idea what the problem might be?
The method showAttentiePopup:
public void showAttentiePopup(AjaxRequestTarget target) {
Component content = new EditAttentiePanel(createAttentie.getContentId(), new Attentie(), EditFunctie.AANMAKEN) {
/** */
private static final long serialVersionUID = 1L;
#Override
protected void annuleren(AjaxRequestTarget target) {
FKSModalWindow.closeCurrentWindow(target);
}
#Override
protected void opslaan(AjaxRequestTarget target, Attentie attentie) {
//Inhoud even weggelaten
}
};
createAttentie.setOutputMarkupId(true);
createAttentie.setInitialWidth(900);
createAttentie.setInitialHeight(450);
createAttentie.setTitle("Nieuwe Attentie Aanmaken");
createAttentie.setContent(content);
createAttentie.show(target);
}
Greetings,
Rick
Your stack trace indicates the ModalWindow createAttentie is not part of a page at the time your code is trying to render it.
Trace through your page construction logic and component structure and make sure everything is wired together correctly.
Related
Hi i am using focus and blur handlers for a flow panel to add outlines. However, i am getting some weird behavior given the code :
panel.addDomHandler(new FocusHandler() {
#Override
public void onFocus(FocusEvent focusEvent) {
panel.addStyleName("FOOSTYLE");
}
}, FocusEvent.getType());
panel.addDomHandler(new BlurHandler() {
FlowPanel _panel = focusPanel;
boolean init = false;
#Override
public void onBlur(BlurEvent blurEvent) {
console.log("Do Blur");
panel.removeStyleName("FOOSTYLE");
}
}, BlurEvent.getType());
The removeStyleName() in the blur handler seems to be called for no reason, also note the log, it's not even executed when the random blur handler gets called, if ever it was.
any suggestions?
To handle focus and blur events you should use FocusPanel. It implements HasFocusHandlers and HasBlurHandlers so you can call addFocusHandler() and addBlurHandler() instead of low-level addDomHandler() method.
If you need to use FlowPanel to lay out your widgets you can add it to the FocusPanel.
I need the URL for a component in wicket. When I use a page it works properly, but when using panel it does not work.
public final class ImageP extends Panel {
public ImageP(String id) {
super(id);
List<Mapp> list = Mapp.loadall(); //load image from database
final Mapp asr = list.get(0);
ByteArrayResource resource = new ByteArrayResource("image/jpeg", asr.getImage());
Image image = new Image("img", resource);
add(image);
System.out.println(getRequestCycle().urlFor(image, IResourceListener.INTERFACE));
}
}
This code does not work and throws an exception, but when I use page instead of panel getRequestCycle().urlFor(image, IResourceListener.INTERFACE) it works properly.
I bet you've got the following exception:
java.lang.IllegalStateException: No Page found for component [Component id = img]
It's because RequestCycle object internally calls getPage() method of the component that's first parameter of the urlFor() method with the following signature:
urlFor(Component component, RequestListenerInterface interface)
In case of calling method urlFor() in the constructor of a panel it's impossible to get page of a panel's child because panel isn't attached to page yet. So Wicket throws "a nice exception".
To fix that problem you just can move your code to the onBeforeRender() method of the panel. Something like that:
#Override
protected void onBeforeRender() {
//
// ... init resource ...
//
Image image = new Image("img", resource);
addOrReplace(image);
System.out.println(getRequestCycle().urlFor(image, IResourceListener.INTERFACE));
super.onBeforeRender();
}
P.S. I also assume that you're using Wicket 1.4 or earlier because there's no RequestCycle.urlFor(component, listener) method in Wicket 1.5 and later. So I think neither your question nor my answer doesn't make sense in that case.
How to defeat IE and Firefox dialog popup when trying to setResponsePage() from a wicket modalWindow per below. Dialog popup demands an answer to: "This page is asking you to confirm that you want to leave - data you have entered may not be saved."
AjaxLink signInContainer = new AjaxLink("signInContainer") {
#Override
public void onClick(AjaxRequestTarget target) {
target.appendJavascript("Wicket.Window.unloadConfirmation = false;");
modalWindow.close(target);
setResponsePage(SignInPage.class);
modalWindow.close(target);
}
};
-Rich
In wicket 6.x and above you can simply set showUnloadConfirmation to false:
final ModalWindow modalWindow = new ModalWindow("modalWindow");
modalWindow.showUnloadConfirmation(false);
target.appendJavascript("Wicket.Window.unloadConfirmation = false;"); doesn't work because it must run before modal.show(target);.
You could either prepend, instead of append, the script, when opening the window:
add(new AjaxLink<Void>("show") {
#Override
public void onClick(AjaxRequestTarget target) {
target.prependJavascript("Wicket.Window.unloadConfirmation = false;");
modal.show(target);
}
});
or add a behavior, to execute it on onload:
modal.add(new AbstractBehavior() {
#Override
public void renderHead(IHeaderResponse response) {
response.renderOnLoadJavascript("Wicket.Window.unloadConfirmation = false;");
}
});
But, it must be called before opening the modal window, not when navigating away from the page (setResponsePage()).
I believe setResponsePage() should be accompanied by some other methods to behave properly. For example, I often include setRedirect(true) when using this technique. I'm not sure what all is going on behind the scenes there, but perhaps try that.
EDIT: This is a hack, use the alternative described in my other answer.
Try this:
public void onClick(AjaxRequestTarget target) {
modal.close(target);
CharSequence url = urlFor(HomePage.class, new PageParameters("gone=true"));
target.appendJavascript("window.location='" + url + "';");
}
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
}
}
}
}
I have 2 inputs. When I press a button(AjaxFallbackButton), those inputs are saved into database.
If one of the input is greater than 10, when I press the button, I want to show a modal panel, for asking the user if is the sure about his option. But the modal component is not appearing. Any thoughts?
#Override
public void onSubmit(AjaxRequestTarget target) {
if (input < 10) { //save to database
} else {
AskingDialogPanel panel = new AskingDialogPanel("content",
new ResourceModel("asking.title"),
new ResourceModel("asking.message")) {
#Override
public void onOkClick(AjaxRequestTarget target) {
super.onOkClick(target);
//save to database
modalWindow.close(target);
}
#Override
public void onCancelClick(AjaxRequestTarget target) {
super.onCancelClick(target);
modalWindow.close(target);
}
};
panel.setOutputMarkupId(true);
target.addComponent(panel);
modalWindow.setContent(panel);
modalWindow.show(target);
}
Have a look at the documentation for the AjaxRequestTarget.
A component whose markup needs to be
updated should be added to this target
via
AjaxRequestTarget#addComponent(Component)
method. Its body will be rendered and
added to the envelope when the target
is processed, and refreshed on the
client side when the ajax response is
received.
I'm not sure if I remember this correctly (I've had trouble implementing the correct refresh behavior previously), but I believe you could only addComponent components that were previously added to the page, but not rendered / invisible. These will than be updated and/or their visibility re-evaluated.
I could be wrong however.. Does the above work if you substitute a normal Label for the AskingDialogPanel? (Just to verify I'm talking out the wrong end ;))